summaryrefslogtreecommitdiff
path: root/src/doc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/doc.rs')
-rw-r--r--src/doc.rs65
1 files changed, 40 insertions, 25 deletions
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() {