From 64e12222bde93e8fbbd977bce7547f50745fbd84 Mon Sep 17 00:00:00 2001 From: quak Date: Sun, 19 Jan 2025 16:38:35 +0100 Subject: [PATCH] changed config-parser macro to check struct hirarchy when parsing configuration file fixed formatting of stack and bookmarks --- .../config-parser-common/src/format.rs | 24 +-- .../src/generator_functions.rs | 64 ++++-- config-parser/config-parser-macro/src/lib.rs | 2 +- src/bookmarks.rs | 4 +- src/config.rs | 6 +- src/stack.rs | 2 +- test.rs | 195 ------------------ 7 files changed, 62 insertions(+), 235 deletions(-) delete mode 100644 test.rs diff --git a/config-parser/config-parser-common/src/format.rs b/config-parser/config-parser-common/src/format.rs index 9bb7a1e..3510e2b 100644 --- a/config-parser/config-parser-common/src/format.rs +++ b/config-parser/config-parser-common/src/format.rs @@ -15,9 +15,9 @@ pub const STYLES: Styles = Styles { bold: "1", dim: "2", italic: "3", - underline: "4", - blink: "5", - reverse: "7", + underlined: "4", + blinking: "5", + reversed: "7", invisible: "8", strikethrough: "9", }, @@ -25,9 +25,9 @@ pub const STYLES: Styles = Styles { bold: "22", dim: "22", italic: "23", - underline: "24", - blink: "25", - reverse: "27", + underlined: "24", + blinking: "25", + reversed: "27", invisible: "28", strikethrough: "29", }, @@ -71,9 +71,9 @@ pub struct StyleCodes { pub bold: &'static str, pub dim: &'static str, pub italic: &'static str, - pub underline: &'static str, - pub blink: &'static str, - pub reverse: &'static str, + pub underlined: &'static str, + pub blinking: &'static str, + pub reversed: &'static str, pub invisible: &'static str, pub strikethrough: &'static str, } @@ -217,9 +217,9 @@ pub fn parse_style(arg: &String) -> Result { "bold" => styles.push(generate_style_sequence(Some(STYLES.set.bold), None, None)), "dim" => styles.push(generate_style_sequence(Some(STYLES.set.dim), None, None)), "italic" => styles.push(generate_style_sequence(Some(STYLES.set.italic), None, None)), - "underlined" => styles.push(generate_style_sequence(Some(STYLES.set.underline), None, None)), - "blink" => styles.push(generate_style_sequence(Some(STYLES.set.blink), None, None)), - "reverse" => styles.push(generate_style_sequence(Some(STYLES.set.reverse), None, None)), + "underlined" => styles.push(generate_style_sequence(Some(STYLES.set.underlined), None, None)), + "blinking" => styles.push(generate_style_sequence(Some(STYLES.set.blinking), None, None)), + "reversed" => styles.push(generate_style_sequence(Some(STYLES.set.reversed), None, None)), "invisible" => styles.push(generate_style_sequence(Some(STYLES.set.invisible), None, None)), "strikethrough" => styles.push(generate_style_sequence(Some(STYLES.set.strikethrough), None, None)), // named colors diff --git a/config-parser/config-parser-macro/src/generator_functions.rs b/config-parser/config-parser-macro/src/generator_functions.rs index ac652e0..e53446e 100644 --- a/config-parser/config-parser-macro/src/generator_functions.rs +++ b/config-parser/config-parser-macro/src/generator_functions.rs @@ -15,24 +15,34 @@ pub fn gen_parse_from_string(config_name: &Ident, output_name: &Ident, assignmen if !#config_name.is_empty() { let leftovers = #config_name.keys().cloned().collect::>(); - return Err(std::io::Error::other(format!("the following settings were not recognised: {:#?}", leftovers))); + #output_name.push(format!("the following settings were not recognised: {:#?}", leftovers)); + } + if !#output_name.is_empty() { + return Err(std::io::Error::other(format!("{}", #output_name.join("\n")))); } Ok(()) } } } -pub fn gen_parse_from_map(config_name: &Ident, assignments: &TokenStream) -> TokenStream { +pub fn gen_parse_from_map(config_name: &Ident, output_name: &Ident, assignments: &TokenStream) -> TokenStream { quote! { /// **do not call** /// this function needs to be public for nested configs but is not intended /// to be called by the user - pub fn parse_from_map(&mut self, input: &mut ConfigMap) -> std::io::Result<()> { - let mut #config_name = input; - let mut output: String = String::new(); + pub fn parse_from_map(&mut self, input: ConfigMap) -> std::io::Result<()> { + let mut #config_name: ConfigMap = input; + let mut #output_name: Vec = Vec::::new(); #assignments + if !#config_name.is_empty() { + let leftovers = #config_name.keys().cloned().collect::>(); + #output_name.push(format!("the following settings were not recognised: {:#?}", leftovers)); + } + if !#output_name.is_empty() { + return Err(std::io::Error::other(format!("{}", #output_name.join("\n")))); + } Ok(()) } } @@ -140,10 +150,14 @@ pub fn gen_config_assignments(fields: &Punctuated, config_map_name Some(attr_name) => { if attr_name.ident == "nested_config" { assignments.extend(quote! { - if let Some(value) = #config_map_name.get(#name_string) { - self.#name.parse_from_map(&mut value); - } else { - #output_name.push(&format!("no table `{}` found in config file", #name_string)); + match #config_map_name.remove(#name_string) { + Some(ConfigElement::Nested(map)) => { + if let Err(error) = self.#name.parse_from_map(map) { + #output_name.push(error.to_string()); + } + }, + Some(ConfigElement::Setting(_)) => #output_name.push(format!("`{}` is defined as a nested element, but the configuration file defines it a setting element", #name_string)), + None => #output_name.push(format!("no table `{}` found in config file", #name_string)), } }); continue 'fields; @@ -157,19 +171,25 @@ pub fn gen_config_assignments(fields: &Punctuated, config_map_name //} else if let Attribute{ meta: Meta::List()} } assignments.extend(quote! { - if let Some(value) = #config_map_name.get(#name_string) { - self.#name = match value.parse::<#ty>() { - Ok(parsed) => { - parsed - }, - Err(_) => { - #output_name.push(format!("failed to parse value found for `{}`", #name_string)); - self.#name.clone() - }, - }; - } else { - #output_name.push(format!("could not find `{}` in config file", #name_string)); - self.#name = self.#name.clone(); + match #config_map_name.remove(#name_string) { + Some(ConfigElement::Setting(value)) => { + self.#name = match value.parse::<#ty>() { + Ok(parsed) => { + parsed + }, + Err(_) => { + #output_name.push(format!("failed to parse value found for `{}`", #name_string)); + self.#name.clone() + }, + }; + }, + Some(ConfigElement::Nested(_)) => { + #output_name.push(format!("`{}` is a setting element, but the configuration file defines it as a nested element (Table)", #name_string)); + }, + None => { + #output_name.push(format!("could not find `{}` in config file", #name_string)); + self.#name = self.#name.clone(); + }, }; }); } diff --git a/config-parser/config-parser-macro/src/lib.rs b/config-parser/config-parser-macro/src/lib.rs index acd9496..f7f48f2 100644 --- a/config-parser/config-parser-macro/src/lib.rs +++ b/config-parser/config-parser-macro/src/lib.rs @@ -32,7 +32,7 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { }; let assignments: TokenStream = gen_config_assignments(fields, &config_name, &output_name); let func_parse_string: TokenStream = gen_parse_from_string(&config_name, &output_name, &assignments); - let func_parse_map: TokenStream = gen_parse_from_map(&config_name, &assignments); + let func_parse_map: TokenStream = gen_parse_from_map(&config_name, &output_name, &assignments); let func_to_ansi_sequences: TokenStream = gen_to_ansi_sequences(fields); let func_default: TokenStream = gen_default(fields); diff --git a/src/bookmarks.rs b/src/bookmarks.rs index 3b4dc8b..9cb9893 100644 --- a/src/bookmarks.rs +++ b/src/bookmarks.rs @@ -114,8 +114,10 @@ impl Bookmarks { &config.format.bookmarks_separator, &config.styles.bookmarks_seperator_style, ); + let mut path = apply_format(path.to_str().unwrap(), &config.styles.bookmarks_path_style); - path = path.replace('/', &format!("{}/{}", config.styles.bookmarks_punct_style, RESET_SEQ)); + path = path.replace('/', &format!("{}/{}{}", config.styles.bookmarks_punct_style, RESET_SEQ, &config.styles.bookmarks_path_style)); + if config.format.align_separators { buffer.push_str(&format!("{}{}{}{}\n", name, padding, separator, path)); } else { diff --git a/src/config.rs b/src/config.rs index d16dd84..879216f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -60,7 +60,7 @@ pub struct StyleSettings { #[default_value("default")] pub stack_path_style: String, #[style_config] - #[default_value("magenta")] + #[default_value("green")] pub stack_punct_style: String, #[style_config] #[default_value("default")] @@ -72,7 +72,7 @@ pub struct StyleSettings { #[default_value("default")] pub bookmarks_path_style: String, #[style_config] - #[default_value("magenta")] + #[default_value("green")] pub bookmarks_punct_style: String, } @@ -81,7 +81,7 @@ impl Config { /// generates and populates a new instance of Config pub fn new(styles_as_ansi_sequences: bool) -> Result { - let mut config = Self::default(); + let mut config: Config = Self::default(); // get configuration directory let mut conf_file = match config_dir() { Some(value) => value, diff --git a/src/stack.rs b/src/stack.rs index ba9e839..178fd6d 100644 --- a/src/stack.rs +++ b/src/stack.rs @@ -49,7 +49,7 @@ impl Stack { &config.styles.stack_separator_style, ); let mut path = apply_format(item.to_str().unwrap(), &config.styles.stack_path_style); - path = path.replace('/', &format!("{}/{}", config.styles.stack_punct_style, RESET_SEQ)); + path = path.replace('/', &format!("{}/{}{}", config.styles.stack_punct_style, RESET_SEQ, config.styles.stack_path_style)); if config.format.align_separators { buffer.push_str(&format!("{}{}{}{}\n", number, padding, separator, path)); } else { diff --git a/test.rs b/test.rs deleted file mode 100644 index f8cf61e..0000000 --- a/test.rs +++ /dev/null @@ -1,195 +0,0 @@ -ast = DeriveInput { - attrs: [], - vis: Visibility::Public( - Pub, - ), - ident: Ident { - ident: "GeneralSettings", - span: #0 bytes(10021..10036), - }, - generics: Generics { - lt_token: None, - params: [], - gt_token: None, - where_clause: None, - }, - data: Data::Struct { - struct_token: Struct, - fields: Fields::Named { - brace_token: Brace, - named: [ - Field { - attrs: [ - Attribute { - pound_token: Pound, - style: AttrStyle::Outer, - bracket_token: Bracket, - meta: Meta::List { - path: Path { - leading_colon: None, - segments: [ - PathSegment { - ident: Ident { - ident: "default_value", - span: #0 bytes(10045..10058), - }, - arguments: PathArguments::None, - }, - ], - }, - delimiter: MacroDelimiter::Paren( - Paren, - ), - tokens: TokenStream [ - Ident { - ident: "false", - span: #0 bytes(10059..10064), - }, - ], - }, - }, - ], - vis: Visibility::Public( - Pub, - ), - mutability: FieldMutability::None, - ident: Some( - Ident { - ident: "show_stack_on_push", - span: #0 bytes(10075..10093), - }, - ), - colon_token: Some( - Colon, - ), - ty: Type::Path { - qself: None, - path: Path { - leading_colon: None, - segments: [ - PathSegment { - ident: Ident { - ident: "bool", - span: #0 bytes(10095..10099), - }, - arguments: PathArguments::None, - }, - ], - }, - }, - }, - Comma, - Field { - attrs: [ - Attribute { - pound_token: Pound, - style: AttrStyle::Outer, - bracket_token: Bracket, - meta: Meta::Path { - leading_colon: None, - segments: [ - PathSegment { - ident: Ident { - ident: "no_config", - span: #0 bytes(10107..10116), - }, - arguments: PathArguments::None, - }, - ], - }, - }, - ], - vis: Visibility::Public( - Pub, - ), - mutability: FieldMutability::None, - ident: Some( - Ident { - ident: "show_stack_on_pop", - span: #0 bytes(10126..10143), - }, - ), - colon_token: Some( - Colon, - ), - ty: Type::Path { - qself: None, - path: Path { - leading_colon: None, - segments: [ - PathSegment { - ident: Ident { - ident: "bool", - span: #0 bytes(10145..10149), - }, - arguments: PathArguments::None, - }, - ], - }, - }, - }, - Comma, - Field { - attrs: [ - Attribute { - pound_token: Pound, - style: AttrStyle::Outer, - bracket_token: Bracket, - meta: Meta::NameValue { - path: Path { - leading_colon: None, - segments: [ - PathSegment { - ident: Ident { - ident: "default_value", - span: #0 bytes(10157..10170), - }, - arguments: PathArguments::None, - }, - ], - }, - eq_token: Eq, - value: Expr::Lit { - attrs: [], - lit: Lit::Bool { - value: false, - }, - }, - }, - }, - ], - vis: Visibility::Public( - Pub, - ), - mutability: FieldMutability::None, - ident: Some( - Ident { - ident: "show_books_on_bookmark", - span: #0 bytes(10188..10210), - }, - ), - colon_token: Some( - Colon, - ), - ty: Type::Path { - qself: None, - path: Path { - leading_colon: None, - segments: [ - PathSegment { - ident: Ident { - ident: "bool", - span: #0 bytes(10212..10216), - }, - arguments: PathArguments::None, - }, - ], - }, - }, - }, - Comma, - ], - }, - semi_token: None, - }, -}