From 32dc66d087075f4b3996db6e0a2778e681a69247 Mon Sep 17 00:00:00 2001 From: Nikolaus Waxweiler Date: Fri, 17 Dec 2021 18:08:25 +0000 Subject: [PATCH] Use LayerInfo struct to deserialize layerinfo.plist --- Cargo.toml | 2 +- src/error.rs | 3 --- src/layer.rs | 43 ++++++++++++++----------------------------- 3 files changed, 15 insertions(+), 33 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9c6378fe..c818de01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ exclude = [ features = ["kurbo"] [dependencies] -plist = { version = "1.2.1", features = ["serde"] } +plist = { version = "1.3.1", features = ["serde"] } uuid = { version = "0.8", features = ["v4"] } serde = { version = "1.0", features = ["rc"] } serde_derive = "1.0" diff --git a/src/error.rs b/src/error.rs index d808d053..dc8c54e3 100644 --- a/src/error.rs +++ b/src/error.rs @@ -91,8 +91,6 @@ pub enum Error { /// /// The string is the dictionary key. ExpectedPlistDictionary(String), - /// An error returned when there is an unexpected plist string. - ExpectedPlistString, /// An error returned when there is an inappropriate negative sign on a value. ExpectedPositiveValue, /// An error returned when there is a problem with kurbo contour conversion. @@ -317,7 +315,6 @@ impl std::fmt::Display for Error { Error::ExpectedPlistDictionary(key) => { write!(f, "Expected a Plist dictionary at '{}'", key) } - Error::ExpectedPlistString => write!(f, "Expected a Plist string."), Error::ExpectedPositiveValue => { write!(f, "PositiveIntegerOrFloat expects a positive value.") } diff --git a/src/layer.rs b/src/layer.rs index f55c6dff..8dd6945f 100644 --- a/src/layer.rs +++ b/src/layer.rs @@ -2,7 +2,6 @@ use std::borrow::Borrow; use std::collections::BTreeMap; use std::fs; use std::path::{Path, PathBuf}; -use std::str::FromStr; use std::sync::Arc; #[cfg(feature = "rayon")] @@ -271,42 +270,28 @@ impl Layer { let layerinfo_path = path.join(LAYER_INFO_FILE); let (color, lib) = if layerinfo_path.exists() { - Self::layerinfo_from_file(&layerinfo_path)? + Self::parse_layer_info(&layerinfo_path)? } else { (None, Plist::new()) }; - // for us to get this far, this mut have a file name + + // for us to get this far, the path must have a file name let path = path.file_name().unwrap().into(); Ok(Layer { glyphs, name, path, contents, color, lib }) } - // Problem: layerinfo.plist contains a nested plist dictionary and the plist crate - // cannot adequately handle that, as ser/de is not implemented for plist::Value. - // Ser/de must be done manually... - fn layerinfo_from_file(path: &Path) -> Result<(Option, Plist), Error> { - let mut info_content = plist::Value::from_file(path) - .map_err(|error| Error::PlistLoad { path: path.to_owned(), error })? - .into_dictionary() - .ok_or_else(|| Error::ExpectedPlistDictionary(path.to_string_lossy().into_owned()))?; - - let mut color = None; - let color_str = info_content.remove("color"); - if let Some(v) = color_str { - match v.into_string() { - Some(s) => color.replace(Color::from_str(&s).map_err(Error::InvalidColor)?), - None => return Err(Error::ExpectedPlistString), - }; - }; - - let lib = match info_content.remove("lib") { - Some(v) => v.into_dictionary().ok_or_else(|| { - Error::ExpectedPlistDictionary(format!("{} (lib)", path.to_string_lossy())) - })?, - None => Plist::new(), - }; - - Ok((color, lib)) + fn parse_layer_info(path: &Path) -> Result<(Option, Plist), Error> { + // Pluck apart the data found in the file, as we want to insert it into `Layer`. + #[derive(Deserialize)] + struct LayerInfoHelper { + color: Option, + #[serde(default)] + lib: Plist, + } + let layerinfo: LayerInfoHelper = plist::from_file(path) + .map_err(|error| Error::PlistLoad { path: path.into(), error })?; + Ok((layerinfo.color, layerinfo.lib)) } fn layerinfo_to_file_if_needed(