From: Ian Jackson Date: Fri, 13 May 2022 23:44:19 +0000 (+0100) Subject: shapelib magic: implement X-Git-Tag: otter-1.1.0~194 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=30b62178ead78399fdcb35c611d87c08a85d75c1;p=otter.git shapelib magic: implement This still has some bugs. We mustn't invoke it just yet in our library bundles, because it will fail. Signed-off-by: Ian Jackson --- diff --git a/src/shapelib-toml.rs b/src/shapelib-toml.rs index f5dfc2d2..367ac628 100644 --- a/src/shapelib-toml.rs +++ b/src/shapelib-toml.rs @@ -33,6 +33,14 @@ pub struct GroupDetails { pub desc_template: Option, pub occulted: Option, pub outline: OutlineDetails, + #[serde(default)] pub magic: Option, +} + +#[derive(Debug,Deserialize)] +pub struct MagicDetails { + #[serde(default)] pub item_prefix: String, + #[serde(default)] pub item_suffix: String, + pub template: String, } #[derive(Debug,Deserialize,Copy,Clone)] diff --git a/src/shapelib.rs b/src/shapelib.rs index d985a05d..8ff12706 100644 --- a/src/shapelib.rs +++ b/src/shapelib.rs @@ -51,7 +51,6 @@ struct ItemDetails { #[derive(Debug,Clone)] enum CatalogueEntry { Item(ItemData), - #[allow(dead_code)] // XXX Magic { group: Arc, spec: Arc }, } use CatalogueEntry as CatEnt; @@ -135,6 +134,9 @@ pub enum LibraryLoadError { #[error("bad item name (invalid characters) in {0:?}")] BadItemName(String), #[error("{0}")] MaterialsFormatVersionError(#[from] MFVE), + #[error("could not parse template-expaneded TOML: {error} (in {toml:?}")] + TemplatedTomlError { toml: String, error: toml_de::Error }, + #[error("group {group}: {error}")] InGroup { group: String, error: Box }, @@ -1228,6 +1230,36 @@ fn process_files_entry( d: Arc::new(ItemDetails { desc }), }; l.add_item(src, src_name, &item_name, CatEnt::Item(idata))?; + + if let Some(magic) = &group.d.magic { + // Ideally the toml crate would have had let us build an inline + // table. But in fact it won't even toml-escape the strings without + // a fuss, so we bodge it with strings: + let image_table = format!( + r#"{{ type="Lib", lib="{}", item="{}" }}"#, + TomlQuote(&l.libname), TomlQuote(item_name.as_str()) + ); + + let item_name = subst_item_name(&format_item_name( + &magic.item_prefix, &fe, &magic.item_suffix)?)?; + + let spec = regex!(r#"(?m)(^[\sA-Za-z0-9._-]+=\s*)!\s*$"#) + .replace_all(&magic.template, |caps: ®ex::Captures| { + format!("{}{}", caps.get(1).unwrap().as_str(), &image_table) + }); + + let spec: Box = toml_de::from_str(&spec) + .map_err(|error| LLE::TemplatedTomlError { + toml: spec.into_owned(), + error, + })?; + + l.add_item(src, src_name, &item_name, CatEnt::Magic { + group: group.clone(), + spec: spec.into(), + })?; + } + Ok::<_,LLE>(()) };