Generalize Refineable derive macro to derive arbitrary traits on the refinement type

Max Brunsfeld created

Change summary

crates/gpui/src/geometry.rs                                  |  6 
crates/gpui2/src/geometry.rs                                 | 10 
crates/gpui2/src/style.rs                                    |  6 
crates/refineable/derive_refineable/src/derive_refineable.rs | 33 +----
crates/theme2/src/colors.rs                                  |  4 
crates/theme2/src/user_theme.rs                              |  5 
6 files changed, 24 insertions(+), 40 deletions(-)

Detailed changes

crates/gpui/src/geometry.rs 🔗

@@ -136,7 +136,7 @@ impl ToJson for RectF {
 }
 
 #[derive(Refineable, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
 pub struct Point<T: Clone + Default + Debug> {
     pub x: T,
     pub y: T,
@@ -161,7 +161,7 @@ impl<T: Clone + Default + Debug> Into<taffy::geometry::Point<T>> for Point<T> {
 }
 
 #[derive(Refineable, Clone, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
 pub struct Size<T: Clone + Default + Debug> {
     pub width: T,
     pub height: T,
@@ -227,7 +227,7 @@ impl Size<Length> {
 }
 
 #[derive(Clone, Default, Refineable, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
 pub struct Edges<T: Clone + Default + Debug> {
     pub top: T,
     pub right: T,

crates/gpui2/src/geometry.rs 🔗

@@ -9,7 +9,7 @@ use std::{
 };
 
 #[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)]
-#[refineable(debug)]
+#[refineable(Debug)]
 #[repr(C)]
 pub struct Point<T: Default + Clone + Debug> {
     pub x: T,
@@ -140,7 +140,7 @@ impl<T: Clone + Default + Debug> Clone for Point<T> {
 }
 
 #[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash, Serialize, Deserialize)]
-#[refineable(debug)]
+#[refineable(Debug)]
 #[repr(C)]
 pub struct Size<T: Clone + Default + Debug> {
     pub width: T,
@@ -313,7 +313,7 @@ impl Size<Length> {
 }
 
 #[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
-#[refineable(debug)]
+#[refineable(Debug)]
 #[repr(C)]
 pub struct Bounds<T: Clone + Default + Debug> {
     pub origin: Point<T>,
@@ -477,7 +477,7 @@ impl Bounds<Pixels> {
 impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
 
 #[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
-#[refineable(debug)]
+#[refineable(Debug)]
 #[repr(C)]
 pub struct Edges<T: Clone + Default + Debug> {
     pub top: T,
@@ -619,7 +619,7 @@ impl Edges<Pixels> {
 }
 
 #[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
-#[refineable(debug)]
+#[refineable(Debug)]
 #[repr(C)]
 pub struct Corners<T: Clone + Default + Debug> {
     pub top_left: T,

crates/gpui2/src/style.rs 🔗

@@ -14,7 +14,7 @@ pub use taffy::style::{
 pub type StyleCascade = Cascade<Style>;
 
 #[derive(Clone, Refineable, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
 pub struct Style {
     /// What layout strategy should be used?
     pub display: Display,
@@ -129,7 +129,7 @@ pub struct BoxShadow {
 }
 
 #[derive(Refineable, Clone, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
 pub struct TextStyle {
     pub color: Hsla,
     pub font_family: SharedString,
@@ -353,7 +353,7 @@ impl Default for Style {
 }
 
 #[derive(Refineable, Copy, Clone, Default, Debug, PartialEq, Eq)]
-#[refineable(debug)]
+#[refineable(Debug)]
 pub struct UnderlineStyle {
     pub thickness: Pixels,
     pub color: Option<Hsla>,

crates/refineable/derive_refineable/src/derive_refineable.rs 🔗

@@ -19,8 +19,7 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
     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;
+    let mut refinement_traits_to_derive = vec![];
 
     if let Some(refineable_attr) = refineable_attr {
         if let Ok(syn::Meta::List(meta_list)) = refineable_attr.parse_meta() {
@@ -29,16 +28,10 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream {
                     continue;
                 };
 
-                if path.is_ident("debug") {
+                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;
+                } else {
+                    refinement_traits_to_derive.push(path);
                 }
             }
         }
@@ -259,22 +252,14 @@ 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 mut derive_stream = quote! {};
+    for trait_to_derive in refinement_traits_to_derive {
+        derive_stream.extend(quote! { #[derive(#trait_to_derive)] })
+    }
 
     let gen = quote! {
         #[derive(Clone)]
-        #derive_serialize
-        #derive_deserialize
+        #derive_stream
         pub struct #refinement_ident #impl_generics {
             #( #field_visibilities #field_names: #wrapped_types ),*
         }

crates/theme2/src/colors.rs 🔗

@@ -14,7 +14,7 @@ pub struct SystemColors {
 }
 
 #[derive(Refineable, Clone, Debug)]
-#[refineable(debug)]
+#[refineable(Debug)]
 pub struct StatusColors {
     pub conflict: Hsla,
     pub created: Hsla,
@@ -30,7 +30,7 @@ pub struct StatusColors {
 }
 
 #[derive(Refineable, Clone, Debug)]
-#[refineable(debug, deserialize)]
+#[refineable(Debug, serde::Deserialize)]
 pub struct ThemeColors {
     pub border: Hsla,
     /// Border color. Used for deemphasized borders, like a visual divider between two sections

crates/theme2/src/user_theme.rs 🔗

@@ -1,8 +1,7 @@
+use crate::{Appearance, ThemeColors, ThemeColorsRefinement};
 use refineable::Refineable;
 use serde::Deserialize;
 
-use crate::{Appearance, ThemeColors, ThemeColorsRefinement};
-
 #[derive(Deserialize)]
 pub struct UserThemeFamily {
     pub name: String,
@@ -18,7 +17,7 @@ pub struct UserTheme {
 }
 
 #[derive(Refineable, Clone)]
-#[refineable(deserialize)]
+#[refineable(Deserialize)]
 pub struct UserThemeStyles {
     #[refineable]
     pub colors: ThemeColors,