From 876bbc50beaf53f83134630a4aaec4c8ddc5d2ec Mon Sep 17 00:00:00 2001 From: Alexandru Placinta Date: Fri, 1 Mar 2024 01:31:19 +0100 Subject: [PATCH] Add alias support to `SerdeReplace` --- CHANGELOG.md | 1 + alacritty_config_derive/src/serde_replace.rs | 38 +++++++++++++--- alacritty_config_derive/tests/config.rs | 46 +++++++++++++++++++- 3 files changed, 78 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e28eadf0..58ce9764 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Autokey no longer working with alacritty on X11 - Freeze when moving window between monitors on Xfwm - Mouse cursor not changing on Wayland when cursor theme uses legacy cursor icon names +- Config keys are available under proper names ### Changed diff --git a/alacritty_config_derive/src/serde_replace.rs b/alacritty_config_derive/src/serde_replace.rs index 0a703b4c..ddd0cf75 100644 --- a/alacritty_config_derive/src/serde_replace.rs +++ b/alacritty_config_derive/src/serde_replace.rs @@ -44,7 +44,10 @@ pub fn derive_recursive( ) -> TokenStream2 { let GenericsStreams { unconstrained, constrained, .. } = crate::generics_streams(&generics.params); - let replace_arms = match_arms(&fields); + let replace_arms = match match_arms(&fields) { + Err(e) => return e.to_compile_error(), + Ok(replace_arms) => replace_arms, + }; quote! { #[allow(clippy::extra_unused_lifetimes)] @@ -75,7 +78,7 @@ pub fn derive_recursive( } /// Create SerdeReplace recursive match arms. -fn match_arms(fields: &Punctuated) -> TokenStream2 { +fn match_arms(fields: &Punctuated) -> Result { let mut stream = TokenStream2::default(); let mut flattened_arm = None; @@ -88,19 +91,42 @@ fn match_arms(fields: &Punctuated) -> TokenStream2 { let flatten = field .attrs .iter() + .filter(|attr| (*attr).path().is_ident("config")) .filter_map(|attr| attr.parse_args::().ok()) .any(|parsed| parsed.ident.as_str() == "flatten"); if flatten && flattened_arm.is_some() { - return Error::new(ident.span(), MULTIPLE_FLATTEN_ERROR).to_compile_error(); + return Err(Error::new(ident.span(), MULTIPLE_FLATTEN_ERROR)); } else if flatten { flattened_arm = Some(quote! { _ => alacritty_config::SerdeReplace::replace(&mut self.#ident, value)?, }); } else { + // Extract all `#[config(alias = "...")]` attribute values. + let aliases = field + .attrs + .iter() + .filter(|attr| (*attr).path().is_ident("config")) + .filter_map(|attr| attr.parse_args::().ok()) + .filter(|parsed| parsed.ident.as_str() == "alias") + .map(|parsed| { + let value = parsed + .param + .ok_or_else(|| format!("Field \"{}\" has no alias value", ident))? + .value(); + + if value.trim().is_empty() { + return Err(format!("Field \"{}\" has an empty alias value", ident)); + } + + Ok(value) + }) + .collect::, String>>() + .map_err(|msg| Error::new(ident.span(), msg))?; + stream.extend(quote! { - #literal => alacritty_config::SerdeReplace::replace(&mut self.#ident, next_value)?, - }); + #(#aliases)|* | #literal => alacritty_config::SerdeReplace::replace(&mut + self.#ident, next_value)?, }); } } @@ -109,5 +135,5 @@ fn match_arms(fields: &Punctuated) -> TokenStream2 { stream.extend(flattened_arm); } - stream + Ok(stream) } diff --git a/alacritty_config_derive/tests/config.rs b/alacritty_config_derive/tests/config.rs index 3130bcda..27a968ed 100644 --- a/alacritty_config_derive/tests/config.rs +++ b/alacritty_config_derive/tests/config.rs @@ -23,7 +23,7 @@ impl Default for TestEnum { #[derive(ConfigDeserialize)] struct Test { - #[config(alias = "noalias")] + #[config(alias = "field1_alias")] #[config(deprecated = "use field2 instead")] field1: usize, #[config(deprecated = "shouldn't be hit")] @@ -39,6 +39,9 @@ struct Test { enom_error: TestEnum, #[config(removed = "it's gone")] gone: bool, + #[config(alias = "multiple_alias1")] + #[config(alias = "multiple_alias2")] + multiple_alias_field: usize, } impl Default for Test { @@ -53,6 +56,7 @@ impl Default for Test { enom_big: TestEnum::default(), enom_error: TestEnum::default(), gone: false, + multiple_alias_field: 0, } } } @@ -70,6 +74,7 @@ struct Test2 { #[derive(ConfigDeserialize, Default)] struct Test3 { + #[config(alias = "flatty_alias")] flatty: usize, } @@ -189,6 +194,33 @@ fn replace_derive() { assert_eq!(test.nesting.newtype, NewType(9)); } +#[test] +fn replace_derive_using_alias() { + let mut test = Test::default(); + + assert_ne!(test.field1, 9); + + let value = toml::from_str("field1_alias=9").unwrap(); + test.replace(value).unwrap(); + + assert_eq!(test.field1, 9); +} + +#[test] +fn replace_derive_using_multiple_aliases() { + let mut test = Test::default(); + + let toml_value = toml::from_str("multiple_alias1=6").unwrap(); + test.replace(toml_value).unwrap(); + + assert_eq!(test.multiple_alias_field, 6); + + let toml_value = toml::from_str("multiple_alias1=7").unwrap(); + test.replace(toml_value).unwrap(); + + assert_eq!(test.multiple_alias_field, 7); +} + #[test] fn replace_flatten() { let mut test = Test::default(); @@ -198,3 +230,15 @@ fn replace_flatten() { assert_eq!(test.flatten.flatty, 7); } + +#[test] +fn replace_flatten_using_alias() { + let mut test = Test::default(); + + assert_ne!(test.flatten.flatty, 7); + + let value = toml::from_str("flatty_alias=7").unwrap(); + test.replace(value).unwrap(); + + assert_eq!(test.flatten.flatty, 7); +}