diff --git a/src/layer.rs b/src/layer.rs index 091e6ae3..452aec15 100644 --- a/src/layer.rs +++ b/src/layer.rs @@ -144,7 +144,7 @@ impl LayerSet { Err(NamingError::Duplicate(name.to_string())) } else { let name = Name::new(name).map_err(|_| NamingError::Invalid(name.into()))?; - let path = crate::util::default_file_name_for_layer_name(&name, &self.path_set); + let path = util::default_file_name_for_layer_name(&name, &self.path_set); let layer = Layer::new(name, path); self.path_set.insert(layer.path.to_string_lossy().to_lowercase()); self.layers.push(layer); @@ -152,6 +152,15 @@ impl LayerSet { } } + /// Returns a mutable reference to a layer, by name, creating the layer if it doesn't exist + pub fn get_or_create_layer(&mut self, name: &str) -> Result<&mut Layer, NamingError> { + let index = self.layers.iter().position(|l| l.name.as_str() == name); + match index { + Some(its_here) => Ok(&mut self.layers[its_here]), + None => self.new_layer(name), + } + } + /// Remove a layer. /// /// The default layer cannot be removed. @@ -729,6 +738,36 @@ mod tests { ); } + #[test] + fn layer_get_or_create() { + let mut ufo = crate::Font::load("testdata/MutatorSansLightWide.ufo").unwrap(); + assert_eq!( + ufo.layers.len(), + 2, + "number of layers in test data MutatorSansLightWide changed" + ); + + let result = ufo.layers.get_or_create_layer("background"); + assert!(result.is_ok()); + assert_eq!(ufo.layers.len(), 2); + + let result = ufo.layers.get_or_create_layer("middleground"); + assert!(result.is_ok()); + assert_eq!(ufo.layers.len(), 3, "new layer wasn't created"); + assert!( + ufo.layers.layers.iter().any(|layer| layer.name().as_str() == "foreground"), + "new layer was created with the wrong name" + ); + + let result = ufo.layers.get_or_create_layer("\t"); + assert!(matches!(result, Err(NamingError::Invalid(_)))); + assert_eq!(ufo.layers.len(), 3); + + let result = ufo.layers.get_or_create_layer(DEFAULT_LAYER_NAME); + assert!(matches!(result, Err(NamingError::ReservedName))); + assert_eq!(ufo.layers.len(), 3); + } + #[test] fn rename_layer() { let mut layer_set = LayerSet::default();