summaryrefslogtreecommitdiff
path: root/src/doc.rs
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2021-10-19 19:30:37 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2021-11-19 20:18:50 +0000
commit5a92266170ae9879b0651e6074e538a4de0a214c (patch)
treed5ecb647701534d6374f441f2c790bfdd2dca848 /src/doc.rs
parent572d3097770cd8e5cd22d7767c1d18e0d50b9a90 (diff)
downloadsubplot-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.rs52
1 files changed, 37 insertions, 15 deletions
diff --git a/src/doc.rs b/src/doc.rs
index ffdd4ac..25dbdb3 100644
--- a/src/doc.rs
+++ b/src/doc.rs
@@ -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 }
}
}