summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bindings.rs26
-rw-r--r--src/codegen.rs13
-rw-r--r--src/diagrams.rs39
-rw-r--r--src/doc.rs65
-rw-r--r--src/error.rs83
-rw-r--r--src/lib.rs1
-rw-r--r--src/matches.rs10
-rw-r--r--src/metadata.rs17
-rw-r--r--src/steps.rs7
-rw-r--r--src/templatespec.rs10
-rw-r--r--subplot-build/src/lib.rs4
11 files changed, 156 insertions, 119 deletions
diff --git a/src/bindings.rs b/src/bindings.rs
index 0837553..5db63c9 100644
--- a/src/bindings.rs
+++ b/src/bindings.rs
@@ -3,7 +3,7 @@ use super::MatchedSteps;
use super::PartialStep;
use super::ScenarioStep;
use super::StepKind;
-use crate::{resource, Result, SubplotError};
+use crate::{resource, SubplotError};
use serde::{Deserialize, Serialize};
use serde_aux::prelude::*;
@@ -54,7 +54,7 @@ pub enum CaptureType {
impl FromStr for CaptureType {
type Err = SubplotError;
- fn from_str(value: &str) -> Result<Self> {
+ fn from_str(value: &str) -> Result<Self, SubplotError> {
match value.to_ascii_lowercase().as_str() {
"word" => Ok(Self::Word),
"text" => Ok(Self::Text),
@@ -168,10 +168,11 @@ impl Binding {
pattern: &str,
case_sensitive: bool,
mut types: HashMap<String, CaptureType>,
- ) -> Result<Binding> {
+ ) -> Result<Binding, SubplotError> {
let regex = RegexBuilder::new(&format!("^{}$", pattern))
.case_insensitive(!case_sensitive)
- .build()?;
+ .build()
+ .map_err(|err| SubplotError::Regex(pattern.to_string(), err))?;
// For every named capture, ensure we have a known type for it.
// If the type is missing from the map, we default to `text` which is
// the .* pattern
@@ -462,8 +463,9 @@ impl Bindings {
}
/// Add bindings from a YAML string
- pub fn add_from_yaml(&mut self, yaml: &str) -> Result<()> {
- let bindings: Vec<ParsedBindingWrapper> = serde_yaml::from_str(yaml)?;
+ pub fn add_from_yaml(&mut self, yaml: &str) -> Result<(), SubplotError> {
+ let bindings: Vec<ParsedBindingWrapper> =
+ serde_yaml::from_str(yaml).map_err(SubplotError::Metadata)?;
for wrapper in bindings {
self.add(from_hashmap(&wrapper.binding)?);
}
@@ -477,7 +479,7 @@ impl Bindings {
/// Find the binding matching a given scenario step, if there is
/// exactly one.
- pub fn find(&self, template: &str, step: &ScenarioStep) -> Result<MatchedStep> {
+ pub fn find(&self, template: &str, step: &ScenarioStep) -> Result<MatchedStep, SubplotError> {
let mut matches: Vec<MatchedStep> = self
.bindings()
.iter()
@@ -499,7 +501,11 @@ impl Bindings {
}
/// Add bindings from a file.
- pub fn add_from_file<P>(&mut self, filename: P, template: Option<&str>) -> Result<()>
+ pub fn add_from_file<P>(
+ &mut self,
+ filename: P,
+ template: Option<&str>,
+ ) -> Result<(), SubplotError>
where
P: AsRef<Path> + Debug,
{
@@ -522,7 +528,7 @@ impl Bindings {
}
}
-fn from_hashmap(parsed: &ParsedBinding) -> Result<Binding> {
+fn from_hashmap(parsed: &ParsedBinding) -> Result<Binding, SubplotError> {
let given: i32 = parsed.given.is_some().into();
let when: i32 = parsed.when.is_some().into();
let then: i32 = parsed.then.is_some().into();
@@ -796,7 +802,7 @@ fn regex_from_simple_pattern(
pattern: &str,
explicit_plain: bool,
types: &mut HashMap<String, CaptureType>,
-) -> Result<String> {
+) -> Result<String, SubplotError> {
let pat = Regex::new(r"\{[^\s\{\}]+\}").unwrap();
let mut r = String::new();
let mut end = 0;
diff --git a/src/codegen.rs b/src/codegen.rs
index b940b4d..5c4255f 100644
--- a/src/codegen.rs
+++ b/src/codegen.rs
@@ -62,12 +62,15 @@ fn tera(tmplspec: &TemplateSpec, templatename: &str) -> Result<Tera, SubplotErro
let dirname = tmplspec.template_filename().parent().unwrap();
for helper in tmplspec.helpers() {
let helper_path = dirname.join(helper);
- let helper_content = resource::read_as_string(helper_path, Some(templatename))?;
+ let helper_content = resource::read_as_string(&helper_path, Some(templatename))
+ .map_err(|err| SubplotError::ReadFile(helper_path.clone(), err))?;
let helper_name = helper.display().to_string();
tera.add_raw_template(&helper_name, &helper_content)
.map_err(|err| SubplotError::TemplateError(helper_name.to_string(), err))?;
}
- let template = resource::read_as_string(tmplspec.template_filename(), Some(templatename))?;
+ let path = tmplspec.template_filename();
+ let template = resource::read_as_string(path, Some(templatename))
+ .map_err(|err| SubplotError::ReadFile(path.to_path_buf(), err))?;
tera.add_raw_template("template", &template)
.map_err(|err| {
SubplotError::TemplateError(tmplspec.template_filename().display().to_string(), err)
@@ -76,8 +79,10 @@ fn tera(tmplspec: &TemplateSpec, templatename: &str) -> Result<Tera, SubplotErro
}
fn write(filename: &Path, content: &str) -> Result<(), SubplotError> {
- let mut f: File = File::create(filename)?;
- f.write_all(content.as_bytes())?;
+ let mut f: File = File::create(filename)
+ .map_err(|err| SubplotError::CreateFile(filename.to_path_buf(), err))?;
+ f.write_all(content.as_bytes())
+ .map_err(|err| SubplotError::WriteFile(filename.to_path_buf(), err))?;
Ok(())
}
diff --git a/src/diagrams.rs b/src/diagrams.rs
index 96f5d70..2bdd0ed 100644
--- a/src/diagrams.rs
+++ b/src/diagrams.rs
@@ -1,4 +1,4 @@
-use crate::{Result, SubplotError};
+use crate::SubplotError;
use std::env;
use std::ffi::OsString;
@@ -72,7 +72,7 @@ lazy_static! {
/// for the trait.
pub trait DiagramMarkup {
/// Convert the markup into an SVG.
- fn as_svg(&self) -> Result<Vec<u8>>;
+ fn as_svg(&self) -> Result<Vec<u8>, SubplotError>;
}
/// A code block with pikchr markup.
@@ -99,7 +99,7 @@ impl PikchrMarkup {
}
impl DiagramMarkup for PikchrMarkup {
- fn as_svg(&self) -> Result<Vec<u8>> {
+ fn as_svg(&self) -> Result<Vec<u8>, SubplotError> {
let mut flags = pikchr::PikchrFlags::default();
flags.generate_plain_errors();
let image = pikchr::Pikchr::render(&self.markup, self.class.as_deref(), flags)
@@ -130,16 +130,22 @@ impl DotMarkup {
}
impl DiagramMarkup for DotMarkup {
- fn as_svg(&self) -> Result<Vec<u8>> {
- let mut child = Command::new(DOT_PATH.lock().unwrap().clone())
+ fn as_svg(&self) -> Result<Vec<u8>, SubplotError> {
+ let path = DOT_PATH.lock().unwrap().clone();
+ let mut child = Command::new(&path)
.arg("-Tsvg")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
- .spawn()?;
+ .spawn()
+ .map_err(|err| SubplotError::Spawn(path.clone(), err))?;
if let Some(stdin) = child.stdin.as_mut() {
- stdin.write_all(self.markup.as_bytes())?;
- let output = child.wait_with_output()?;
+ stdin
+ .write_all(self.markup.as_bytes())
+ .map_err(SubplotError::WriteToChild)?;
+ let output = child
+ .wait_with_output()
+ .map_err(SubplotError::WaitForChild)?;
if output.status.success() {
Ok(output.stdout)
} else {
@@ -191,8 +197,9 @@ impl PlantumlMarkup {
}
impl DiagramMarkup for PlantumlMarkup {
- fn as_svg(&self) -> Result<Vec<u8>> {
- let mut cmd = Command::new(JAVA_PATH.lock().unwrap().clone());
+ fn as_svg(&self) -> Result<Vec<u8>, SubplotError> {
+ let path = JAVA_PATH.lock().unwrap().clone();
+ let mut cmd = Command::new(&path);
cmd.arg("-Djava.awt.headless=true")
.arg("-jar")
.arg(PLANTUML_JAR_PATH.lock().unwrap().clone())
@@ -208,10 +215,16 @@ impl DiagramMarkup for PlantumlMarkup {
if let Some(path) = Self::build_java_path() {
cmd.env("PATH", path);
}
- let mut child = cmd.spawn()?;
+ let mut child = cmd
+ .spawn()
+ .map_err(|err| SubplotError::Spawn(path.clone(), err))?;
if let Some(stdin) = child.stdin.as_mut() {
- stdin.write_all(self.markup.as_bytes())?;
- let output = child.wait_with_output()?;
+ stdin
+ .write_all(self.markup.as_bytes())
+ .map_err(SubplotError::WriteToChild)?;
+ let output = child
+ .wait_with_output()
+ .map_err(SubplotError::WaitForChild)?;
if output.status.success() {
Ok(output.stdout)
} else {
diff --git a/src/doc.rs b/src/doc.rs
index ed88e95..71266d6 100644
--- a/src/doc.rs
+++ b/src/doc.rs
@@ -11,8 +11,8 @@ use crate::PartialStep;
use crate::Scenario;
use crate::ScenarioStep;
use crate::Style;
+use crate::SubplotError;
use crate::{bindings::CaptureType, parser::parse_scenario_snippet};
-use crate::{Result, SubplotError};
use crate::{Warning, Warnings};
use std::collections::HashSet;
@@ -118,7 +118,7 @@ impl<'a> Document {
mut ast: Pandoc,
style: Style,
template: Option<&str>,
- ) -> Result<Document>
+ ) -> Result<Document, SubplotError>
where
P: AsRef<Path> + Debug,
{
@@ -143,12 +143,12 @@ impl<'a> Document {
json: &str,
style: Style,
template: Option<&str>,
- ) -> Result<Document>
+ ) -> Result<Document, SubplotError>
where
P: AsRef<Path> + Debug,
{
trace!("Parsing document...");
- let ast: Pandoc = serde_json::from_str(json)?;
+ let ast: Pandoc = serde_json::from_str(json).map_err(SubplotError::AstJson)?;
Self::from_ast(basedir, markdowns, ast, style, template)
}
@@ -162,7 +162,7 @@ impl<'a> Document {
filename: &Path,
style: Style,
template: Option<&str>,
- ) -> Result<Document> {
+ ) -> Result<Document, SubplotError> {
trace!(
"Document::from_file: basedir={} filename={}",
basedir.display(),
@@ -183,7 +183,7 @@ impl<'a> Document {
crate::policy::add_citeproc(&mut pandoc);
trace!("Invoking Pandoc to parse document {:?}", filename);
- let output = match pandoc.execute()? {
+ let output = match pandoc.execute().map_err(SubplotError::Pandoc)? {
pandoc::PandocOutput::ToBuffer(o) => o,
_ => return Err(SubplotError::NotJson),
};
@@ -203,10 +203,11 @@ impl<'a> Document {
filename: &Path,
style: Style,
template: Option<&str>,
- ) -> Result<Document> {
+ ) -> Result<Document, SubplotError> {
trace!("Parsing document with pullmark-cmark from {:?}", filename);
let filename = filename.to_path_buf();
- let markdown = std::fs::read_to_string(&filename)?;
+ let markdown = std::fs::read_to_string(&filename)
+ .map_err(|err| SubplotError::ReadFile(filename.clone(), err))?;
let ast = ast::AbstractSyntaxTree::from_str(&markdown)?;
trace!("Parsed document OK");
@@ -217,8 +218,8 @@ impl<'a> Document {
///
/// This is useful in a Pandoc filter, so that the filter can give
/// it back to Pandoc for typesetting.
- pub fn ast(&self) -> Result<String> {
- let json = serde_json::to_string(&self.ast)?;
+ pub fn ast(&self) -> Result<String, SubplotError> {
+ let json = serde_json::to_string(&self.ast).map_err(SubplotError::AstJson)?;
Ok(json)
}
@@ -277,7 +278,7 @@ impl<'a> Document {
}
/// Check the document for common problems.
- pub fn lint(&self) -> Result<()> {
+ pub fn lint(&self) -> Result<(), SubplotError> {
trace!("Linting document");
self.check_doc_has_title()?;
self.check_filenames_are_unique()?;
@@ -287,7 +288,7 @@ impl<'a> Document {
}
// Check that all filenames for embedded files are unique.
- fn check_filenames_are_unique(&self) -> Result<()> {
+ fn check_filenames_are_unique(&self) -> Result<(), SubplotError> {
let mut known = HashSet::new();
for filename in self.files().iter().map(|f| f.filename().to_lowercase()) {
if known.contains(&filename) {
@@ -299,7 +300,7 @@ impl<'a> Document {
}
// Check that document has a title in its metadata.
- fn check_doc_has_title(&self) -> Result<()> {
+ fn check_doc_has_title(&self) -> Result<(), SubplotError> {
if self.meta().title().is_empty() {
Err(SubplotError::NoTitle)
} else {
@@ -308,7 +309,7 @@ impl<'a> Document {
}
/// Check that all the block classes in the document are known
- fn check_block_classes(&self) -> Result<()> {
+ fn check_block_classes(&self) -> Result<(), SubplotError> {
let mut visitor = visitor::BlockClassVisitor::default();
// Irritatingly we can't immutably visit the AST for some reason
// This clone() is expensive and unwanted, but I'm not sure how
@@ -341,7 +342,7 @@ impl<'a> Document {
/// Check that all named files (in matched steps) are actually present in the
/// document.
- pub fn check_named_files_exist(&mut self, template: &str) -> Result<bool> {
+ pub fn check_named_files_exist(&mut self, template: &str) -> Result<bool, SubplotError> {
let filenames: HashSet<_> = self
.files()
.iter()
@@ -374,7 +375,7 @@ impl<'a> Document {
}
/// Check that all embedded files are used by matched steps.
- pub fn check_embedded_files_are_used(&mut self, template: &str) -> Result<bool> {
+ pub fn check_embedded_files_are_used(&mut self, template: &str) -> Result<bool, SubplotError> {
let mut filenames: HashSet<_> = self
.files()
.iter()
@@ -442,7 +443,7 @@ impl<'a> Document {
}
/// Return all scenarios in a document.
- pub fn scenarios(&mut self) -> Result<Vec<Scenario>> {
+ pub fn scenarios(&mut self) -> Result<Vec<Scenario>, SubplotError> {
let mut visitor = visitor::StructureVisitor::new();
visitor.walk_pandoc(&mut self.ast);
@@ -460,7 +461,10 @@ impl<'a> Document {
}
/// Return matched scenarios in a document.
- pub fn matched_scenarios(&mut self, template: &str) -> Result<Vec<MatchedScenario>> {
+ pub fn matched_scenarios(
+ &mut self,
+ template: &str,
+ ) -> Result<Vec<MatchedScenario>, SubplotError> {
let scenarios = self.scenarios()?;
trace!(
"Found {} scenarios, checking their bindings",
@@ -474,7 +478,7 @@ impl<'a> Document {
}
/// Extract a template name from this document
- pub fn template(&self) -> Result<&str> {
+ pub fn template(&self) -> Result<&str, SubplotError> {
let templates: Vec<_> = self.meta().templates().collect();
if templates.len() == 1 {
Ok(templates[0])
@@ -489,7 +493,11 @@ impl<'a> Document {
/// Load a `Document` from a file.
///
/// This version uses Pandoc to parse the Markdown.
-pub fn load_document<P>(filename: P, style: Style, template: Option<&str>) -> Result<Document>
+pub fn load_document<P>(
+ filename: P,
+ style: Style,
+ template: Option<&str>,
+) -> Result<Document, SubplotError>
where
P: AsRef<Path> + Debug,
{
@@ -514,7 +522,7 @@ pub fn load_document_with_pullmark<P>(
filename: P,
style: Style,
template: Option<&str>,
-) -> Result<Document>
+) -> Result<Document, SubplotError>
where
P: AsRef<Path> + Debug,
{
@@ -533,7 +541,11 @@ where
}
/// Generate code for one document.
-pub fn codegen(filename: &Path, output: &Path, template: Option<&str>) -> Result<CodegenOutput> {
+pub fn codegen(
+ filename: &Path,
+ output: &Path,
+ template: Option<&str>,
+) -> Result<CodegenOutput, SubplotError> {
let r = load_document_with_pullmark(filename, Style::default(), template);
let mut doc = match r {
Ok(doc) => doc,
@@ -577,7 +589,7 @@ impl CodegenOutput {
}
}
-fn extract_scenario(e: &[visitor::Element]) -> Result<(Option<Scenario>, usize)> {
+fn extract_scenario(e: &[visitor::Element]) -> Result<(Option<Scenario>, usize), SubplotError> {
if e.is_empty() {
// If we get here, it's a programming error.
panic!("didn't expect empty list of elements");
@@ -625,7 +637,6 @@ fn extract_scenario(e: &[visitor::Element]) -> Result<(Option<Scenario>, usize)>
mod test_extract {
use super::extract_scenario;
use super::visitor::Element;
- use crate::Result;
use crate::Scenario;
use crate::SubplotError;
@@ -637,7 +648,11 @@ mod test_extract {
Element::Snippet(text.to_string())
}
- fn check_result(r: Result<(Option<Scenario>, usize)>, title: Option<&str>, i: usize) {
+ fn check_result(
+ r: Result<(Option<Scenario>, usize), SubplotError>,
+ title: Option<&str>,
+ i: usize,
+ ) {
assert!(r.is_ok());
let (actual_scen, actual_i) = r.unwrap();
if title.is_none() {
diff --git a/src/error.rs b/src/error.rs
index c93141e..a42298d 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -259,60 +259,48 @@ pub enum SubplotError {
#[error("no scenarios were found matching the `{0}` template")]
NoScenariosMatched(String),
- /// I/O error
- ///
- /// Subplot did some I/O, and it failed. This is a generic wrapper
- /// for any kind of I/O error.
- #[error(transparent)]
- IoError {
- /// The wrapped error.
- #[from]
- source: std::io::Error,
- },
+ /// Failed to invoke a program.
+ #[error("Failed to invoke {0}")]
+ Spawn(PathBuf, #[source] std::io::Error),
- /// Pandoc error
- ///
- /// Subplot got an error from Panoc. This is a generic wrapper for
- /// any kinds of Pandoc errors.
- #[error(transparent)]
- PandocError {
- /// The wrapped error.
- #[from]
- source: pandoc::PandocError,
- },
+ /// Failed to write to stdin of child process.
+ #[error("Failed to write to stdin of child process")]
+ WriteToChild(#[source] std::io::Error),
+
+ /// Error when waiting for child process to finish.
+ #[error("Error when waiting for child process to finish")]
+ WaitForChild(#[source] std::io::Error),
+
+ /// Error when reading a file.
+ #[error("Error when reading {0}")]
+ ReadFile(PathBuf, #[source] std::io::Error),
+
+ /// Error when creating a file.
+ #[error("Error when creating {0}")]
+ CreateFile(PathBuf, #[source] std::io::Error),
+
+ /// Error when writing to a file.
+ #[error("Error when writing to {0}")]
+ WriteFile(PathBuf, #[source] std::io::Error),
+
+ /// Error executing Pandoc.
+ #[error("Pandoc failed")]
+ Pandoc(#[source] pandoc::PandocError),
/// Regular expression error
///
/// Subplot uses regular expressions. This is a generic wrapper for
/// any kinds of errors related to that.
- #[error(transparent)]
- RegexError {
- /// The wrapped error.
- #[from]
- source: regex::Error,
- },
+ #[error("Failed to compile regular expression: {0:?}")]
+ Regex(String, #[source] regex::Error),
- /// JSON error
- ///
- /// Subplot parses and generates JSON. This is a generic wrapper
- /// for any kinds of errors related to that.
- #[error(transparent)]
- JsonError {
- /// The wrapped error.
- #[from]
- source: serde_json::Error,
- },
+ /// Error parsing the Pandoc abstract syntax tree as JSON.
+ #[error("Failed to parse document AST as JSON")]
+ AstJson(#[source] serde_json::Error),
- /// YAML error
- ///
- /// Subplot parses YAML. This is a generic wrapper for any kinds
- /// of errors related to that.
- #[error(transparent)]
- YamlError {
- /// The wrapped error.
- #[from]
- source: serde_yaml::Error,
- },
+ /// Error parsing YAML metadata for document.
+ #[error("Failed to parse YAML metadata")]
+ Metadata(#[source] serde_yaml::Error),
/// Abstract syntax tree error.
#[error(transparent)]
@@ -336,9 +324,6 @@ impl SubplotError {
}
}
-/// A result type for this crate.
-pub type Result<T> = std::result::Result<T, SubplotError>;
-
/// A warning, or non-fatal error.
///
/// Errors prevent Subplot from producing output. Warnings don't do that.
diff --git a/src/lib.rs b/src/lib.rs
index d253765..3b4e844 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,7 +14,6 @@ extern crate pandoc_ast_07 as pandoc_ast;
extern crate pandoc_ast_08 as pandoc_ast;
mod error;
-pub use error::Result;
pub use error::SubplotError;
pub use error::Warning;
pub use error::Warnings;
diff --git a/src/matches.rs b/src/matches.rs
index f8e527a..9130641 100644
--- a/src/matches.rs
+++ b/src/matches.rs
@@ -1,7 +1,7 @@
use crate::Binding;
-use crate::Result;
use crate::Scenario;
use crate::StepKind;
+use crate::SubplotError;
use crate::{bindings::CaptureType, Bindings};
use std::collections::HashMap;
@@ -17,8 +17,12 @@ pub struct MatchedScenario {
impl MatchedScenario {
/// Construct a new matched scenario
- pub fn new(template: &str, scen: &Scenario, bindings: &Bindings) -> Result<MatchedScenario> {
- let steps: Result<Vec<MatchedStep>> = scen
+ pub fn new(
+ template: &str,
+ scen: &Scenario,
+ bindings: &Bindings,
+ ) -> Result<MatchedScenario, SubplotError> {
+ let steps: Result<Vec<MatchedStep>, SubplotError> = scen
.steps()
.iter()
.map(|step| bindings.find(template, step))
diff --git a/src/metadata.rs b/src/metadata.rs
index 0248891..5f5e183 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -1,5 +1,4 @@
-use crate::Result;
-use crate::{Bindings, TemplateSpec};
+use crate::{Bindings, SubplotError, TemplateSpec};
use std::collections::HashMap;
use std::fmt::Debug;
@@ -31,7 +30,11 @@ pub struct DocumentImpl {
impl Metadata {
/// Construct a Metadata from a Document, if possible.
- pub fn new<P>(basedir: P, doc: &Pandoc, template: Option<&str>) -> Result<Metadata>
+ pub fn new<P>(
+ basedir: P,
+ doc: &Pandoc,
+ template: Option<&str>,
+ ) -> Result<Metadata, SubplotError>
where
P: AsRef<Path> + Debug,
{
@@ -152,7 +155,7 @@ fn get_bindings_filenames(map: &Mapp) -> Vec<PathBuf> {
get_paths("", map, "bindings")
}
-fn load_template_spec(template: &str) -> Result<TemplateSpec> {
+fn load_template_spec(template: &str) -> Result<TemplateSpec, SubplotError> {
let mut spec_path = PathBuf::from(template);
spec_path.push("template");
spec_path.push("template.yaml");
@@ -298,7 +301,11 @@ mod test_join {
}
}
-fn get_bindings<P>(filenames: &[P], bindings: &mut Bindings, template: Option<&str>) -> Result<()>
+fn get_bindings<P>(
+ filenames: &[P],
+ bindings: &mut Bindings,
+ template: Option<&str>,
+) -> Result<(), SubplotError>
where
P: AsRef<Path> + Debug,
{
diff --git a/src/steps.rs b/src/steps.rs
index c8c1bf6..ccbc588 100644
--- a/src/steps.rs
+++ b/src/steps.rs
@@ -1,4 +1,4 @@
-use crate::{Result, SubplotError};
+use crate::SubplotError;
use serde::{Deserialize, Serialize};
use std::fmt;
@@ -47,7 +47,10 @@ impl ScenarioStep {
///
/// If the step uses the "and" or "but" keyword, use the default
/// step kind instead.
- pub fn new_from_str(text: &str, default: Option<StepKind>) -> Result<ScenarioStep> {
+ pub fn new_from_str(
+ text: &str,
+ default: Option<StepKind>,
+ ) -> Result<ScenarioStep, SubplotError> {
let mut words = text.split_whitespace();
let keyword = match words.next() {
diff --git a/src/templatespec.rs b/src/templatespec.rs
index 5d7150b..28ab7e1 100644
--- a/src/templatespec.rs
+++ b/src/templatespec.rs
@@ -1,5 +1,4 @@
use crate::resource;
-use crate::Result;
use crate::SubplotError;
use serde::Deserialize;
@@ -21,8 +20,8 @@ pub struct TemplateSpec {
impl TemplateSpec {
// Create a new TemplateSpec from YAML text.
- fn from_yaml(yaml: &str) -> Result<TemplateSpec> {
- Ok(serde_yaml::from_str(yaml)?)
+ fn from_yaml(yaml: &str) -> Result<TemplateSpec, SubplotError> {
+ serde_yaml::from_str(yaml).map_err(SubplotError::Metadata)
}
// Create a new TemplateSpec.
@@ -40,8 +39,9 @@ impl TemplateSpec {
}
/// Read a template.yaml file and create the corresponding TemplateSpec.
- pub fn from_file(filename: &Path) -> Result<TemplateSpec> {
- let yaml = resource::read_as_string(filename, None)?;
+ pub fn from_file(filename: &Path) -> Result<TemplateSpec, SubplotError> {
+ let yaml = resource::read_as_string(filename, None)
+ .map_err(|err| SubplotError::ReadFile(filename.to_path_buf(), err))?;
let spec = TemplateSpec::from_yaml(&yaml)?;
let dirname = match filename.parent() {
Some(x) => x,
diff --git a/subplot-build/src/lib.rs b/subplot-build/src/lib.rs
index 28558e8..f8ed074 100644
--- a/subplot-build/src/lib.rs
+++ b/subplot-build/src/lib.rs
@@ -7,7 +7,7 @@
use std::env::var_os;
use std::fmt::Debug;
use std::path::{Path, PathBuf};
-use subplot::{get_basedir_from, Result};
+use subplot::{get_basedir_from, SubplotError};
use tracing::{event, instrument, span, Level};
/// Generate code for one document, inside `build.rs`.
@@ -31,7 +31,7 @@ use tracing::{event, instrument, span, Level};
/// # dir.close().unwrap()
/// ```
#[instrument(level = "trace")]
-pub fn codegen<P>(filename: P) -> Result<()>
+pub fn codegen<P>(filename: P) -> Result<(), SubplotError>
where
P: AsRef<Path> + Debug,
{