summaryrefslogtreecommitdiff
path: root/src/metadata.rs
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2021-11-12 10:59:10 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2021-11-19 20:19:00 +0000
commit03f4bff558807c3bf6b6ebd65aa1e547b9286461 (patch)
tree59c8b2ed142f7625916f2610713727f1537d03f2 /src/metadata.rs
parent73e7188b2397d1afb5c550cf8863157c9174a4e5 (diff)
downloadsubplot-03f4bff558807c3bf6b6ebd65aa1e547b9286461.tar.gz
subplot: Rework for impls not template/functions
As the next step in polyglot documents, this reworks the internals to expect the metadata of documents to contain an impls mapping from template name to function filenames for that template. Sadly this does mean that if there're no function files, the document author will have to still specify an empty list, but that seems acceptable. Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'src/metadata.rs')
-rw-r--r--src/metadata.rs74
1 files changed, 33 insertions, 41 deletions
diff --git a/src/metadata.rs b/src/metadata.rs
index 03d4eff..0d0e844 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -32,14 +32,13 @@ pub struct DocumentImpl {
impl Metadata {
/// Construct a Metadata from a Document, if possible.
#[instrument(level = "trace", skip(doc))]
- pub fn new<P>(basedir: P, doc: &Pandoc) -> Result<Metadata>
+ pub fn new<P>(basedir: P, doc: &Pandoc, template: Option<&str>) -> Result<Metadata>
where
P: AsRef<Path> + Debug,
{
let title = get_title(&doc.meta);
let date = get_date(&doc.meta);
let bindings_filenames = get_bindings_filenames(&doc.meta);
- let functions_filenames = get_functions_filenames(&doc.meta);
let bibliographies = get_bibliographies(basedir.as_ref(), &doc.meta);
let classes = get_classes(&doc.meta);
event!(
@@ -47,31 +46,41 @@ impl Metadata {
?title,
?date,
?bindings_filenames,
- ?functions_filenames,
?bibliographies,
?classes,
"Loaded basic metadata"
);
- let (template, spec) = if let Some((template, spec)) = get_template_spec(&doc.meta)? {
- (Some(template), Some(spec))
- } else {
- (None, None)
- };
- event!(Level::TRACE, ?template, ?spec, "Loaded template spec");
- let mut bindings = Bindings::new();
- get_bindings(&bindings_filenames, &mut bindings, template.as_deref())?;
- event!(Level::TRACE, "Loaded all metadata successfully");
let mut impls = HashMap::new();
- if let (Some(template), Some(spec)) = (template, spec) {
- let mut docimpl = DocumentImpl::new(spec);
- for fname in functions_filenames {
- docimpl.add_function_file(fname);
+ if let Some(raw_impls) = doc.meta.get("impls") {
+ match raw_impls {
+ MetaValue::MetaMap(raw_impls) => {
+ for (impl_name, functions_filenames) in raw_impls.iter() {
+ let template_spec = load_template_spec(impl_name)?;
+ let filenames = pathbufs("", functions_filenames);
+ let docimpl = DocumentImpl::new(template_spec, filenames);
+ impls.insert(impl_name.to_string(), docimpl);
+ }
+ }
+ _ => {
+ event!(
+ Level::WARN,
+ value = ?raw_impls,
+ "Ignoring unknown raw implementation value"
+ );
+ }
}
- impls.insert(template, docimpl);
}
+ let template = template.or_else(|| impls.keys().next().map(String::as_str));
+
+ let mut bindings = Bindings::new();
+
+ get_bindings(&bindings_filenames, &mut bindings, template.as_deref())?;
+
+ event!(Level::TRACE, "Loaded all metadata successfully");
+
Ok(Metadata {
title,
date,
@@ -125,15 +134,8 @@ impl Metadata {
}
impl DocumentImpl {
- fn new(spec: TemplateSpec) -> Self {
- Self {
- spec,
- functions: Vec::new(),
- }
- }
-
- fn add_function_file(&mut self, function: PathBuf) {
- self.functions.push(function);
+ fn new(spec: TemplateSpec, functions: Vec<PathBuf>) -> Self {
+ Self { spec, functions }
}
pub fn functions_filenames(&self) -> impl Iterator<Item = &Path> {
@@ -163,21 +165,11 @@ fn get_bindings_filenames(map: &Mapp) -> Vec<PathBuf> {
get_paths("", map, "bindings")
}
-fn get_functions_filenames(map: &Mapp) -> Vec<PathBuf> {
- get_paths("", map, "functions")
-}
-
-fn get_template_spec(map: &Mapp) -> Result<Option<(String, TemplateSpec)>> {
- match get_string(map, "template") {
- Some(s) => {
- let mut spec_path = PathBuf::from(&s);
- spec_path.push("template");
- spec_path.push("template.yaml");
- let spec = TemplateSpec::from_file(&spec_path)?;
- Ok(Some((s, spec)))
- }
- None => Ok(None),
- }
+fn load_template_spec(template: &str) -> Result<TemplateSpec> {
+ let mut spec_path = PathBuf::from(template);
+ spec_path.push("template");
+ spec_path.push("template.yaml");
+ TemplateSpec::from_file(&spec_path)
}
fn get_paths<P>(basedir: P, map: &Mapp, field: &str) -> Vec<PathBuf>