From 2e0cd4e0f00919705cf0ed335b177e6722e60744 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 8 May 2022 11:55:52 +0100 Subject: [PATCH] mformat 2: Deserialise the data that library format 2 needs Introduce the various enums (including serde(untagged) ones) so that we can deserialise all of the mf1 and mf2 formats into the same structure. Signed-off-by: Ian Jackson --- src/shapelib-toml.rs | 42 ++++++++++++++++++++++++++++++++++++++++-- src/shapelib.rs | 26 +++++++++++++++++++++----- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/src/shapelib-toml.rs b/src/shapelib-toml.rs index e8eb2a0c..0def8998 100644 --- a/src/shapelib-toml.rs +++ b/src/shapelib-toml.rs @@ -26,11 +26,49 @@ pub struct GroupDetails { #[serde(default)] pub centre: Option<[f64; 2]>, #[serde(default)] pub flip: bool, #[serde(default)] pub back: Option>, - #[serde(default="num_traits::identities::One::one")] pub scale: f64, + #[serde(default)] pub scale: Option, #[serde(default)] pub colours: HashMap, pub desc_template: Option, pub occulted: Option, - #[serde(flatten)] pub outline: Box, + #[serde(flatten)] pub outline: OutlineDetails, +} + +#[derive(Debug,Deserialize,Copy,Clone)] +#[serde(untagged)] +pub enum ScaleDetails { + Fit(ScaleFitDetails), + Scale(f64), + Stretch([f64;2]), +} + +#[derive(Debug,Deserialize,Copy,Clone)] +pub enum ScaleFitDetails { Fit, Cover, Stretch } + +#[derive(Debug,Deserialize)] +#[serde(untagged)] +pub enum OutlineDetails { + Full(FullOutlineDetails), // introduced with mformat=2 + Shape(Box), +} + +#[derive(Debug,Deserialize)] +pub struct FullOutlineDetails { + shape: Box, + #[serde(default)] size: Vec, + #[serde(default)] scale: Option, +} + +impl OutlineDetails { + // enum_access could perhaps do this but controlling the serde + // would become confusing + pub fn shape(&self) -> &dyn shapelib::OutlineDefn { match self { + OutlineDetails::Full(full) => &*full.shape, + OutlineDetails::Shape(shape) => &**shape, + }} + pub fn size_scale(&self) -> (&[f64], Option<&f64>) { match self { + OutlineDetails::Full(full) => (&full.size, full.scale.as_ref()), + OutlineDetails::Shape(_) => default(), + }} } #[derive(Deserialize,Clone,Debug)] diff --git a/src/shapelib.rs b/src/shapelib.rs index 0812eb88..ca59bbcf 100644 --- a/src/shapelib.rs +++ b/src/shapelib.rs @@ -590,7 +590,7 @@ impl FaceTransform { .into_inner() .unwrap() } else { - let s = d.scale; + let s = group.d.scale_mf1(group.mformat)?; [s,s] }; let centre = d.centre.map(Ok).unwrap_or_else(|| Ok::<_,LLE>({ @@ -646,11 +646,22 @@ impl GroupData { #[throws(LibraryLoadError)] fn load_shape(&self, svg_sz: PosC) -> (FaceTransform, Outline) { let xform = FaceTransform::from_group_mf1(self)?; - let outline = self.d.outline.load_mf1(&self, svg_sz)?; + let outline = self.d.outline.shape().load_mf1(&self, svg_sz)?; (xform, outline) } } +impl GroupDetails { + #[throws(materials_format::Incompat)] + fn scale_mf1(&self, mformat: materials_format::Version) -> f64 { + match self.scale { + None => 1., + Some(ScaleDetails::Scale(s)) => s, + _ => throw!(mformat.incompat(LLMI::Scale)), + } + } +} + //---------- RectShape ---------- #[derive(Clone,Copy,Debug,Serialize,Deserialize)] @@ -862,9 +873,14 @@ pub fn load_catalogue(libname: &str, src: &mut dyn LibrarySource) let gdefn = resolve_inherit(INHERIT_DEPTH_LIMIT, groups, groupname, gdefn)?; let gdefn: GroupDefn = TV::Table(gdefn.into_owned()).try_into()?; - let d = GroupDetails { - size: gdefn.d.size.iter().map(|s| s * gdefn.d.scale).collect(), - ..gdefn.d + let d = if mformat == 1 { + let scale = gdefn.d.scale_mf1(mformat)?; + GroupDetails { + size: gdefn.d.size.iter().map(|s| s * scale).collect(), + ..gdefn.d + } + } else { + gdefn.d // v2 isn't going to do this, do this right now }; let group = Arc::new(GroupData { groupname: groupname.clone(), -- 2.30.2