diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2021-10-19 19:30:37 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2021-11-19 20:18:50 +0000 |
commit | 5a92266170ae9879b0651e6074e538a4de0a214c (patch) | |
tree | d5ecb647701534d6374f441f2c790bfdd2dca848 /src/doc.rs | |
parent | 572d3097770cd8e5cd22d7767c1d18e0d50b9a90 (diff) | |
download | subplot-5a92266170ae9879b0651e6074e538a4de0a214c.tar.gz |
various: Rework document to support multiple implementations
In order to eventually shift the document metadata to support
more than one template defined for the document this reworks
all the internal APIs to expect templates, and also the external
CLI to be able to provide it.
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'src/doc.rs')
-rw-r--r-- | src/doc.rs | 52 |
1 files changed, 37 insertions, 15 deletions
@@ -12,7 +12,6 @@ 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; @@ -216,15 +215,27 @@ impl<'a> Document { /// /// The sources are any files that affect the output so that if /// the source file changes, the output needs to be re-generated. - pub fn sources(&mut self) -> Vec<PathBuf> { + pub fn sources(&mut self, template: Option<&str>) -> Vec<PathBuf> { let mut names = vec![]; for x in self.meta().bindings_filenames() { names.push(PathBuf::from(x)) } - for x in self.meta().functions_filenames() { - names.push(PathBuf::from(x)) + if let Some(template) = template { + if let Some(spec) = self.meta().document_impl(template) { + for x in spec.functions_filenames() { + names.push(PathBuf::from(x)); + } + } + } else { + for template in self.meta().templates() { + if let Some(spec) = self.meta().document_impl(template) { + for x in spec.functions_filenames() { + names.push(PathBuf::from(x)); + } + } + } } for x in self.meta().bibliographies().iter() { @@ -422,6 +433,18 @@ impl<'a> Document { .map(|scen| MatchedScenario::new(template, scen, bindings)) .collect() } + + /// Extract a template name from this document + pub fn template(&self) -> Result<&str> { + let templates: Vec<_> = self.meta().templates().collect(); + if templates.len() == 1 { + Ok(templates[0]) + } else if templates.is_empty() { + Err(SubplotError::MissingTemplate) + } else { + Err(SubplotError::AmbiguousTemplate) + } + } } /// Load a `Document` from a file. @@ -475,16 +498,15 @@ where } /// Generate code for one document. -pub fn codegen(filename: &Path, output: &Path) -> Result<CodegenOutput> { +pub fn codegen(filename: &Path, output: &Path, template: Option<&str>) -> 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)? + let template = template + .map(Ok) + .unwrap_or_else(|| doc.template())? .to_string(); event!(Level::TRACE, ?template); if !doc.check_named_files_exist(&template)? || !doc.check_matched_steps_have_impl(&template) { @@ -494,21 +516,21 @@ pub fn codegen(filename: &Path, output: &Path) -> Result<CodegenOutput> { } event!(Level::TRACE, "Generating code"); - let spec = template_spec(&doc)?; - generate_test_program(&mut doc, &spec, output, &template)?; + + generate_test_program(&mut doc, output, &template)?; event!(Level::TRACE, "Finished generating code"); - Ok(CodegenOutput::new(spec, doc)) + Ok(CodegenOutput::new(template, doc)) } pub struct CodegenOutput { - pub spec: TemplateSpec, + pub template: String, pub doc: Document, } impl CodegenOutput { - fn new(spec: TemplateSpec, doc: Document) -> Self { - Self { spec, doc } + fn new(template: String, doc: Document) -> Self { + Self { template, doc } } } |