Allow deriving Serialize and Deserialize on generated refinement (#3227)

This PR adds support for deriving `Serialize` and `Deserialize` on the
refinement type generated by `#[derive(Refineable)]`.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2023-11-03 22:21:00 +01:00 committed by GitHub
parent edacffab58
commit 287ea0a6e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 4 deletions

View file

@ -16,9 +16,33 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
..
} = parse_macro_input!(input);
let impl_debug_on_refinement = attrs
.iter()
.any(|attr| attr.path.is_ident("refineable") && attr.tokens.to_string().contains("debug"));
let refineable_attr = attrs.iter().find(|attr| attr.path.is_ident("refineable"));
let mut impl_debug_on_refinement = false;
let mut derive_serialize_on_refinement = false;
let mut derive_deserialize_on_refinement = false;
if let Some(refineable_attr) = refineable_attr {
if let Ok(syn::Meta::List(meta_list)) = refineable_attr.parse_meta() {
for nested in meta_list.nested {
let syn::NestedMeta::Meta(syn::Meta::Path(path)) = nested else {
continue;
};
if path.is_ident("debug") {
impl_debug_on_refinement = true;
}
if path.is_ident("serialize") {
derive_serialize_on_refinement = true;
}
if path.is_ident("deserialize") {
derive_deserialize_on_refinement = true;
}
}
}
}
let refinement_ident = format_ident!("{}Refinement", ident);
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
@ -235,8 +259,22 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
quote! {}
};
let derive_serialize = if derive_serialize_on_refinement {
quote! { #[derive(serde::Serialize)]}
} else {
quote! {}
};
let derive_deserialize = if derive_deserialize_on_refinement {
quote! { #[derive(serde::Deserialize)]}
} else {
quote! {}
};
let gen = quote! {
#[derive(Clone)]
#derive_serialize
#derive_deserialize
pub struct #refinement_ident #impl_generics {
#( #field_visibilities #field_names: #wrapped_types ),*
}

View file

@ -49,7 +49,7 @@ pub struct GitStatusColors {
}
#[derive(Refineable, Clone, Debug)]
#[refineable(debug)]
#[refineable(debug, deserialize)]
pub struct ThemeColors {
pub border: Hsla,
pub border_variant: Hsla,
@ -105,6 +105,8 @@ pub struct ThemeStyles {
#[cfg(test)]
mod tests {
use serde_json::json;
use super::*;
#[test]
@ -146,4 +148,16 @@ mod tests {
assert_eq!(colors.text, magenta);
assert_eq!(colors.background, green);
}
#[test]
fn deserialize_theme_colors_refinement_from_json() {
let colors: ThemeColorsRefinement = serde_json::from_value(json!({
"background": "#ff00ff",
"text": "#ff0000"
}))
.unwrap();
assert_eq!(colors.background, Some(gpui::rgb(0xff00ff)));
assert_eq!(colors.text, Some(gpui::rgb(0xff0000)));
}
}