From 5e54453433fc7475b1e8e3edaafc4ce368f9da6c Mon Sep 17 00:00:00 2001 From: Alain Emilia Anna Zscheile Date: Fri, 6 Dec 2024 16:13:19 +0100 Subject: [PATCH] refactor(specctra-core/read): accept multiple possible names anywhere Previously, some methods handled items/lists with multiple allowed names, and some only allowed a single name. As the overhead of always handling multiple names isn't that large, do that everywhere and make the overall API more streamlined in the process. --- crates/specctra-core/src/common.rs | 21 ++++++++----- crates/specctra-core/src/read.rs | 44 ++++++++------------------- crates/specctra-core/src/structure.rs | 16 +++++----- crates/specctra_derive/src/read.rs | 4 +-- 4 files changed, 36 insertions(+), 49 deletions(-) diff --git a/crates/specctra-core/src/common.rs b/crates/specctra-core/src/common.rs index 9a52ec4..cdd49b2 100644 --- a/crates/specctra-core/src/common.rs +++ b/crates/specctra-core/src/common.rs @@ -7,15 +7,22 @@ pub enum ListToken { } impl ListToken { - pub fn expect_start(self, name: &'static str) -> Result<(), ParseError> { + pub fn is_start_of(&self, valid_names: &[&'static str]) -> bool { if let Self::Start { name: actual_name } = self { - if name.eq_ignore_ascii_case(&actual_name) { - Ok(()) - } else { - Err(ParseError::ExpectedStartOfList(name)) - } + valid_names + .iter() + .any(|i| i.eq_ignore_ascii_case(actual_name)) } else { - Err(ParseError::ExpectedStartOfList(name)) + false + } + } + + pub fn expect_start(self, valid_names: &[&'static str]) -> Result<(), ParseError> { + assert!(!valid_names.is_empty()); + if self.is_start_of(valid_names) { + Ok(()) + } else { + Err(ParseError::ExpectedStartOfList(valid_names[0])) } } diff --git a/crates/specctra-core/src/read.rs b/crates/specctra-core/src/read.rs index ee36c3c..9b94b02 100644 --- a/crates/specctra-core/src/read.rs +++ b/crates/specctra-core/src/read.rs @@ -13,9 +13,9 @@ impl InputToken { Self { token, context } } - pub fn expect_start(self, name: &'static str) -> Result<(), ParseErrorContext> { + pub fn expect_start(self, valid_names: &[&'static str]) -> Result<(), ParseErrorContext> { self.token - .expect_start(name) + .expect_start(valid_names) .map_err(|err| err.add_context(self.context)) } @@ -295,9 +295,9 @@ impl ListTokenizer { pub fn read_named>( &mut self, - name: &'static str, + valid_names: &[&'static str], ) -> Result { - self.consume_token()?.expect_start(name)?; + self.consume_token()?.expect_start(valid_names)?; let value = self.read_value::()?; self.consume_token()?.expect_end()?; Ok(value) @@ -308,27 +308,14 @@ impl ListTokenizer { valid_names: &[&'static str], ) -> Result, ParseErrorContext> { let input = self.consume_token()?; - Ok( - if let ListToken::Start { - name: ref actual_name, - } = input.token - { - if valid_names - .iter() - .any(|i| i.eq_ignore_ascii_case(actual_name)) - { - let value = self.read_value::()?; - self.consume_token()?.expect_end()?; - Some(value) - } else { - self.return_token(input); - None - } - } else { - self.return_token(input); - None - }, - ) + Ok(if input.token.is_start_of(valid_names) { + let value = self.read_value::()?; + self.consume_token()?.expect_end()?; + Some(value) + } else { + self.return_token(input); + None + }) } pub fn read_array>(&mut self) -> Result, ParseErrorContext> { @@ -347,13 +334,6 @@ impl ListTokenizer { } pub fn read_named_array>( - &mut self, - name: &'static str, - ) -> Result, ParseErrorContext> { - self.read_array_with_alias(&[name]) - } - - pub fn read_array_with_alias>( &mut self, valid_names: &[&'static str], ) -> Result, ParseErrorContext> { diff --git a/crates/specctra-core/src/structure.rs b/crates/specctra-core/src/structure.rs index aaa8f9a..7c4ad6d 100644 --- a/crates/specctra-core/src/structure.rs +++ b/crates/specctra-core/src/structure.rs @@ -103,18 +103,18 @@ pub struct Structure { impl ReadDsn for Structure { fn read_dsn(tokenizer: &mut ListTokenizer) -> Result { let mut value = Self { - layers: tokenizer.read_named_array("layer")?, - boundary: tokenizer.read_named("boundary")?, - planes: tokenizer.read_named_array("plane")?, - keepouts: tokenizer.read_named_array("keepout")?, - via: tokenizer.read_named("via")?, - grids: tokenizer.read_named_array("grid")?, - rules: tokenizer.read_named_array("rule")?, + layers: tokenizer.read_named_array(&["layer"])?, + boundary: tokenizer.read_named(&["boundary"])?, + planes: tokenizer.read_named_array(&["plane"])?, + keepouts: tokenizer.read_named_array(&["keepout"])?, + via: tokenizer.read_named(&["via"])?, + grids: tokenizer.read_named_array(&["grid"])?, + rules: tokenizer.read_named_array(&["rule"])?, }; value .layers - .append(&mut tokenizer.read_named_array("layer")?); + .append(&mut tokenizer.read_named_array(&["layer"])?); Ok(value) } diff --git a/crates/specctra_derive/src/read.rs b/crates/specctra_derive/src/read.rs index 19461d6..d2a11bf 100644 --- a/crates/specctra_derive/src/read.rs +++ b/crates/specctra_derive/src/read.rs @@ -61,7 +61,7 @@ fn impl_field(field: &Field) -> TokenStream { } FieldType::NamedVec(valid_aliases) => { quote! { - #name: tokenizer.read_array_with_alias(&[#(#valid_aliases),*])?, + #name: tokenizer.read_named_array(&[#(#valid_aliases),*])?, } } FieldType::NotSpecified => { @@ -79,7 +79,7 @@ fn impl_field(field: &Field) -> TokenStream { } quote! { - #name: tokenizer.read_named(stringify!(#name_str))?, + #name: tokenizer.read_named(&[stringify!(#name_str)])?, } } }