chiark / gitweb /
wip new shapelib (build broken...)
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 14 Sep 2020 00:58:25 +0000 (01:58 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 14 Sep 2020 00:58:25 +0000 (01:58 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/shapelib.rs

index 98502bc1509d8c60d57e8527faa99e521a4344c3..e8c6eabbb6fd87ac74542e757e104eb9be316b11 100644 (file)
@@ -4,20 +4,38 @@
 
 pub use crate::imports::*;
 
-#[derive(Deserialize,Debug)]
-#[serde(transparent)]
-pub struct Library {
-  pub sections: LinkedHashMap<String, Section>,
+#[derive(Debug)]
+pub struct LibraryContents {
+  pub directory: String,
+  pub pieces: HashMap<String /* usvg path */, LibraryPieceInfo>,
 }
 
-#[derive(Deserialize,Debug)]
-pub struct Section {
+#[derive(Debug)]
+pub struct LibraryPieceInfo {
+  pub desc: Html,
+  pub info: Arc<LibraryGroupInfo>,
+}
+
+#[derive(Debug,Deserialize)]
+pub struct LibraryGroupInfo {
   pub outline: Box<dyn OutlineSpec>,
   pub size: Vec<Coord>,
-  pub middle: Option<Vec<f64>>,
+  #[serde(default="num_traits::identities::One::one")]
+  pub scale: f64,
+  #[serde(default)]
+  pub centre: Option<Vec<f64>>,
   pub category: String,
+}
+
+#[derive(Debug,Deserialize)]
+struct LibraryGroupSpec {
+  #[serde(transparent)]
+  pub info: Arc<LibraryGroupInfo>,
+  #[serde(default)]
+  pub stem_prefix: String,
+  #[serde(default)]
+  pub stem_suffix: String,
   pub files: FileList,
-  pub scraper: Option<toml::Value>,
 }
 
 #[derive(Deserialize,Debug)]
@@ -41,9 +59,44 @@ pub enum LibraryLoadError{
   #[error("error reading/opening library file: {0}")]
   FileError(#[from] io::Error),
   #[error("{:?}",&self)]
+  ExpectedTable(String),
+  #[error("{:?}",&self)]
+  InheritMissingParentGroup(String,String),
+  #[error("{:?}",&self)]
+  InheritDepthLimitExceeded(String),
+  #[error("{:?}",&self)]
+  DuplicateFile(String,LibraryPieceInfo,LibraryPieceInfo),
+  #[error("{:?}",&self)]
   FilesListLineMissingWhitespace(usize),
 }
 
+const INHERIT_DEPTH_LIMIT : u8 = 20;
+
+type LLE = LibraryLoadError;
+
+#[throws(LibraryLoadError)]
+fn resolve_inherit(depth: u8, groups: &toml::Table, group_name: &str,
+                   group: &'g toml::Value) -> Cow<'g, toml::Table> {
+  let gn = || format!("{}", group_name);
+  let gp = || format!("group.{}", group_name);
+
+  let group = group.as_table().ok_or_else(|| LLE::ExpectedTable(gp()))?;
+
+  let parent_name = match group.get("inherit") {
+    None => { return Cow::Borrowed(group) },
+    Some(p) = p,
+  };
+  let parent = groups.get(parent_name)
+    .ok_or_else(|| LLE::MissingParentGroup(gn(), parent_name.to_string))?;
+
+  let mut build = parent.resolve_inherit(
+    depth.checked_sub(1).ok_or_else(!| LLE:InheritDepthLimitExceeded(gn()))?,
+    groups, parent_name, parent);
+
+  build.extend(group.iter());
+  build
+}
+
 impl Library {
   #[throws(LibraryLoadError)]
   pub fn load(path: &str) -> Library {
@@ -51,13 +104,35 @@ impl Library {
     let mut f = BufReader::new(f);
     let mut s = String::new();
     f.read_to_string(&mut s).unwrap();
-    let l : shapelib::Library = toml::from_str(&s)?;
+    let toplevel : toml::Value = s.parse()?;
+    let mut l = LibraryContents { pieces: HashMap::new() };
+    let groups =
+      toplevel
+      .as_table().ok_or_else(|| LLE::ExpectedTable(format!("toplevel")))?;
+      .get("group").or_else(toml::value::Value::Table(Default::default()))
+      .as_table().ok_or_else(|| LLE::ExpectedTable(format!("group")))?;
+    for (group_name, group_value) in groups {
+      let resolved = resolve_inherit(INHERIT_DEPTH_LIMIT,
+                                     &groups, group_name, group_value);
+      let spec : LibraryGroupSpec = resolved.try_into()?;
+      for f in spec.files {
+        let usvgfile = format!("{}{}{}.usvg",
+                               spec.stem_prefix, f.filespec, spec.stem_suffix);
+        let lp = LibraryPieceInfo { info, desc: fileentry.desc };
+        match l.entry(usvgfile) {
+          Occupied(oe) => throw!(LLE::DuplicateFile(
+            oe.key().clone(),
+            oe.get().clone(),
+            lp,
+          )),
+          Vacant(ve) => ve.insert(lp),
+        };
+      }
+    }
     l
   }
 }
 
-type LLE = LibraryLoadError;
-
 #[derive(Deserialize,Debug)]
 struct Circle { }
 #[typetag::deserialize]