From ad80e43612084e6e164bc3a5de794e2b8d480e34 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 14 May 2022 00:01:18 +0100 Subject: [PATCH] shapelib: Introduce CatalogueEntry enum Currently it only has one variant, but this gets us the plumbing. Signed-off-by: Ian Jackson --- src/shapelib.rs | 70 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/src/shapelib.rs b/src/shapelib.rs index d02c8d76..3aa1a917 100644 --- a/src/shapelib.rs +++ b/src/shapelib.rs @@ -39,7 +39,7 @@ pub struct Catalogue { libname: String, dirname: String, bundle: Option, - items: HashMap, ItemData>, + items: HashMap, CatalogueEntry>, } #[derive(Debug,Clone)] @@ -48,6 +48,12 @@ struct ItemDetails { desc: Html, } +#[derive(Debug,Clone)] +enum CatalogueEntry { + Item(ItemData), +} +use CatalogueEntry as CatEnt; + #[derive(Debug,Clone)] struct ItemData { d: Arc, @@ -414,7 +420,7 @@ impl From for SpecLoaded { impl ItemSpec { #[throws(SpecError)] fn find_then(&self, ig: &Instance, then: F) -> T - where F: FnOnce(&Catalogue, &SvgBaseName, &ItemData) + where F: FnOnce(&Catalogue, &SvgBaseName, &CatalogueEntry) -> Result { let regs = ig.all_shapelibs(); @@ -427,11 +433,25 @@ impl ItemSpec { } #[throws(SpecError)] - fn find_load(&self, ig: &Instance, - depth: SpecDepth) -> ItemSpecLoaded { - self.find_then(ig, |lib, item, idata| { - lib.load1(idata, &self.lib, item.unnest::(), ig, depth) - })? + fn find_load_general(&self, ig: &Instance, depth: SpecDepth, + mundanef: MUN) -> T + where MUN: FnOnce(ItemSpecLoaded) -> Result, + { + self.find_then(ig, |lib, item, catent| Ok(match catent { + CatEnt::Item(idata) => { + let loaded = lib.load1(idata, &self.lib, item.unnest::(), + ig, depth)?; + mundanef(loaded)? + }, + }))? + } + + #[throws(SpecError)] + pub fn find_load_mundane(&self, ig: &Instance, + depth: SpecDepth) -> ItemSpecLoaded { + self.find_load_general( + ig, depth, |loaded| Ok(loaded), + )? } fn from_strs(lib: &L, item: &I) -> Self @@ -447,12 +467,15 @@ impl ItemSpec { #[typetag::serde(name="Lib")] impl PieceSpec for ItemSpec { #[throws(SpecError)] - fn load(&self, PLA { ig,depth,.. }: PLA) -> SpecLoaded { - self.find_load(ig,depth)?.into() + fn load(&self, pla: PLA) -> SpecLoaded { + self.find_load_general( + pla.ig, pla.depth, + |loaded| Ok(loaded.into()), + )? } #[throws(SpecError)] fn load_inert(&self, ig: &Instance, depth: SpecDepth) -> SpecLoadedInert { - let (p, occultable) = self.find_load(ig,depth)?; + let (p, occultable) = self.find_load_mundane(ig,depth)?; SpecLoadedInert { p: p as _, occultable } } } @@ -463,14 +486,15 @@ impl PieceSpec for MultiSpec { fn count(&self, _pcaliases: &PieceAliases) -> usize { self.items.len() } #[throws(SpecError)] - fn load(&self, PLA { i,ig,depth,.. }: PLA) -> SpecLoaded + fn load(&self, pla: PLA) -> SpecLoaded { + let PLA { i,.. } = pla; let item = self.items.get(i).ok_or_else( || SpE::InternalError(format!("item {:?} from {:?}", i, &self)) )?; let item = format!("{}{}{}", &self.prefix, item, &self.suffix); let lib = self.lib.clone(); - ItemSpec { lib, item }.find_load(ig,depth)?.into() + ItemSpec { lib, item }.load(pla)? } } @@ -640,6 +664,12 @@ fn resolve_square_size(size: &[T]) -> Option> { } }) } +impl CatalogueEntry { + fn group(&self) -> &Arc { match self { + CatEnt::Item(item) => &item.group, + } } +} + //---------- Outlines ---------- impl ShapeCalculable { @@ -922,10 +952,14 @@ impl Catalogue { for (k,v) in &self.items { if !pat.matches(k.as_str()) { continue } let gpc = GPiece::dummy(); - let (loaded, _) = match - self.load1(v, &self.libname, k.unnest(), - &Instance::dummy(), SpecDepth::zero()) - { + let loaded = match (|| Ok(match v { + CatEnt::Item(item) => { + let (loaded, _) = + self.load1(item, &self.libname, k.unnest(), + &Instance::dummy(), SpecDepth::zero())?; + loaded as Box + }, + }))() { Err(SpecError::LibraryItemNotFound(_)) => continue, e@ Err(_) => e?, Ok(r) => r, @@ -1120,12 +1154,12 @@ pub fn load_catalogue(libname: &str, src: &mut dyn LibrarySource) match l.items.entry(new_item) { H::Occupied(oe) => throw!(LLE::DuplicateItem { item: item_name.as_str().to_owned(), - group1: oe.get().group.groupname.clone(), + group1: oe.get().group().groupname.clone(), group2: groupname.clone(), }), H::Vacant(ve) => { debug!("loaded shape {} {}", libname, item_name.as_str()); - ve.insert(idata); + ve.insert(CatEnt::Item(idata)); } }; Ok::<_,LLE>(()) -- 2.30.2