diff options
Diffstat (limited to 'alacritty_config_derive/src/serde_replace.rs')
-rw-r--r-- | alacritty_config_derive/src/serde_replace.rs | 38 |
1 files changed, 32 insertions, 6 deletions
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<T>( ) -> 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<T>( } /// Create SerdeReplace recursive match arms. -fn match_arms<T>(fields: &Punctuated<Field, T>) -> TokenStream2 { +fn match_arms<T>(fields: &Punctuated<Field, T>) -> Result<TokenStream2, syn::Error> { let mut stream = TokenStream2::default(); let mut flattened_arm = None; @@ -88,19 +91,42 @@ fn match_arms<T>(fields: &Punctuated<Field, T>) -> TokenStream2 { let flatten = field .attrs .iter() + .filter(|attr| (*attr).path().is_ident("config")) .filter_map(|attr| attr.parse_args::<Attr>().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::<Attr>().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::<Result<Vec<String>, 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<T>(fields: &Punctuated<Field, T>) -> TokenStream2 { stream.extend(flattened_arm); } - stream + Ok(stream) } |