diff options
Diffstat (limited to 'src/doc.rs')
-rw-r--r-- | src/doc.rs | 93 |
1 files changed, 92 insertions, 1 deletions
@@ -1,4 +1,6 @@ use crate::ast; +use crate::generate_test_program; +use crate::get_basedir_from; use crate::visitor; use crate::DataFile; use crate::DataFiles; @@ -10,6 +12,7 @@ use crate::Scenario; use crate::ScenarioStep; use crate::Style; use crate::{bindings::CaptureType, parser::parse_scenario_snippet}; +use crate::{template_spec, TemplateSpec}; use crate::{Result, SubplotError}; use std::collections::HashSet; @@ -21,7 +24,7 @@ use std::str::FromStr; use pandoc_ast::{MutVisitor, Pandoc}; -use tracing::{event, instrument, Level}; +use tracing::{event, instrument, span, Level}; /// The set of known (special) classes which subplot will always recognise /// as being valid. @@ -421,6 +424,94 @@ impl<'a> Document { } } +/// Load a `Document` from a file. +/// +/// This version uses Pandoc to parse the Markdown. +#[instrument(level = "trace")] +pub fn load_document<P>(filename: P, style: Style) -> Result<Document> +where + P: AsRef<Path> + Debug, +{ + let filename = filename.as_ref(); + let base_path = get_basedir_from(filename); + event!( + Level::TRACE, + ?filename, + ?base_path, + "Loading document based at `{}` called `{}` with {:?}", + base_path.display(), + filename.display(), + style + ); + let doc = Document::from_file(&base_path, filename, style)?; + event!(Level::TRACE, "Loaded doc from file OK"); + + Ok(doc) +} + +/// Load a `Document` from a file. +/// +/// This version uses the `cmark-pullmark` crate to parse Markdown. +#[instrument(level = "trace")] +pub fn load_document_with_pullmark<P>(filename: P, style: Style) -> Result<Document> +where + P: AsRef<Path> + Debug, +{ + let filename = filename.as_ref(); + let base_path = get_basedir_from(filename); + event!( + Level::TRACE, + ?filename, + ?base_path, + "Loading document based at `{}` called `{}` with {:?} using pullmark-cmark", + base_path.display(), + filename.display(), + style + ); + crate::resource::add_search_path(filename.parent().unwrap()); + let doc = Document::from_file_with_pullmark(&base_path, filename, style)?; + event!(Level::TRACE, "Loaded doc from file OK"); + Ok(doc) +} + +/// Generate code for one document. +pub fn codegen(filename: &Path, output: &Path) -> Result<CodegenOutput> { + let span = span!(Level::TRACE, "codegen"); + let _enter = span.enter(); + + let mut doc = load_document_with_pullmark(filename, Style::default())?; + doc.lint()?; + let template = doc + .meta() + .template_name() + .ok_or(SubplotError::MissingTemplate)? + .to_string(); + event!(Level::TRACE, ?template); + if !doc.check_named_files_exist(&template)? || !doc.check_matched_steps_have_impl(&template) { + event!(Level::ERROR, "Found problems in document, cannot continue"); + eprintln!("Unable to continue"); + std::process::exit(1); + } + + event!(Level::TRACE, "Generating code"); + let spec = template_spec(&doc)?; + generate_test_program(&mut doc, &spec, output, &template)?; + event!(Level::TRACE, "Finished generating code"); + + Ok(CodegenOutput::new(spec, doc)) +} + +pub struct CodegenOutput { + pub spec: TemplateSpec, + pub doc: Document, +} + +impl CodegenOutput { + fn new(spec: TemplateSpec, doc: Document) -> Self { + Self { spec, doc } + } +} + fn extract_scenario(e: &[visitor::Element]) -> Result<(Option<Scenario>, usize)> { if e.is_empty() { // If we get here, it's a programming error. |