Change summary
crates/refineable/derive_refineable/src/derive_refineable.rs | 44 +++++
crates/theme2/src/colors.rs | 16 ++
2 files changed, 56 insertions(+), 4 deletions(-)
Detailed changes
@@ -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 ),*
}
@@ -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)));
+ }
}