Revert "Add a proc macro for deriving override structs with optional fields"

Nathan Sobo created

This reverts commit ab9356e9d83635978a1cb305d4f017f9a1d57dec.

Change summary

crates/gpui/playground/src/components.rs               |   5 
crates/gpui/playground/src/element.rs                  | 100 +++++----
crates/gpui/playground/src/frame.rs                    |  38 ++-
crates/gpui/playground/src/playground.rs               |   8 
crates/gpui/playground/src/style.rs                    |  11 -
crates/gpui/playground/src/text.rs                     |  10 
crates/gpui/playground_macros/src/derive_element.rs    |   8 
crates/gpui/playground_macros/src/derive_overrides.rs  | 119 ------------
crates/gpui/playground_macros/src/playground_macros.rs |   6 
9 files changed, 96 insertions(+), 209 deletions(-)

Detailed changes

crates/gpui/playground/src/components.rs 🔗

@@ -1,6 +1,6 @@
 use crate::{
-    div,
     element::{Element, ElementMetadata},
+    frame,
     text::ArcCow,
     themes::rose_pine,
 };
@@ -82,9 +82,8 @@ pub fn button<V>() -> Button<V, ()> {
 impl<V: 'static, D: 'static> Button<V, D> {
     fn render(&mut self, view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
         // TODO: Drive theme from the context
-        let button = div()
+        let button = frame()
             .fill(rose_pine::dawn().error(0.5))
-            // .hover_fill(rose_pine::dawn().error(0.6))
             .h_4()
             .children(self.label.clone());
 

crates/gpui/playground/src/element.rs 🔗

@@ -1,7 +1,7 @@
 use crate::{
     adapter::Adapter,
     color::Hsla,
-    style::{Display, ElementStyle, ElementStyleOverrides, Fill, Overflow, Position},
+    style::{Display, ElementStyle, Fill, Overflow, Position},
 };
 use anyhow::Result;
 pub use gpui::LayoutContext;
@@ -27,7 +27,6 @@ pub struct Layout<'a, E: ?Sized> {
 
 pub struct ElementMetadata<V> {
     pub style: ElementStyle,
-    pub hover_style: ElementStyleOverrides,
     pub handlers: Vec<EventHandler<V>>,
 }
 
@@ -51,7 +50,6 @@ impl<V> Default for ElementMetadata<V> {
     fn default() -> Self {
         Self {
             style: ElementStyle::default(),
-            hover_style: ElementStyleOverrides::default(),
             handlers: Vec::new(),
         }
     }
@@ -60,7 +58,8 @@ impl<V> Default for ElementMetadata<V> {
 pub trait Element<V: 'static>: 'static {
     type Layout: 'static;
 
-    fn metadata(&mut self) -> &mut ElementMetadata<V>;
+    fn style_mut(&mut self) -> &mut ElementStyle;
+    fn handlers_mut(&mut self) -> &mut Vec<EventHandler<V>>;
 
     fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>)
         -> Result<(NodeId, Self::Layout)>;
@@ -127,7 +126,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().handlers.push(EventHandler {
+        self.handlers_mut().push(EventHandler {
             handler: Rc::new(move |view, event, event_cx| {
                 let event = event.downcast_ref::<MouseButtonEvent>().unwrap();
                 if event.button == button && event.is_down {
@@ -148,7 +147,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().handlers.push(EventHandler {
+        self.handlers_mut().push(EventHandler {
             handler: Rc::new(move |view, event, event_cx| {
                 let event = event.downcast_ref::<MouseButtonEvent>().unwrap();
                 if event.button == button && event.is_down {
@@ -169,7 +168,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().handlers.push(EventHandler {
+        self.handlers_mut().push(EventHandler {
             handler: Rc::new(move |view, event, event_cx| {
                 let event = event.downcast_ref::<MouseButtonEvent>().unwrap();
                 if event.button == button && !event.is_down {
@@ -190,7 +189,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().handlers.push(EventHandler {
+        self.handlers_mut().push(EventHandler {
             handler: Rc::new(move |view, event, event_cx| {
                 let event = event.downcast_ref::<MouseButtonEvent>().unwrap();
                 if event.button == button && !event.is_down {
@@ -209,7 +208,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.display = Display::Block;
+        self.style_mut().display = Display::Block;
         self
     }
 
@@ -217,7 +216,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.display = Display::Flex;
+        self.style_mut().display = Display::Flex;
         self
     }
 
@@ -225,7 +224,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.display = Display::Grid;
+        self.style_mut().display = Display::Grid;
         self
     }
 
@@ -235,8 +234,8 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.overflow.x = Overflow::Visible;
-        self.metadata().style.overflow.y = Overflow::Visible;
+        self.style_mut().overflow.x = Overflow::Visible;
+        self.style_mut().overflow.y = Overflow::Visible;
         self
     }
 
@@ -244,8 +243,8 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.overflow.x = Overflow::Hidden;
-        self.metadata().style.overflow.y = Overflow::Hidden;
+        self.style_mut().overflow.x = Overflow::Hidden;
+        self.style_mut().overflow.y = Overflow::Hidden;
         self
     }
 
@@ -253,8 +252,8 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.overflow.x = Overflow::Scroll;
-        self.metadata().style.overflow.y = Overflow::Scroll;
+        self.style_mut().overflow.x = Overflow::Scroll;
+        self.style_mut().overflow.y = Overflow::Scroll;
         self
     }
 
@@ -262,7 +261,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.overflow.x = Overflow::Visible;
+        self.style_mut().overflow.x = Overflow::Visible;
         self
     }
 
@@ -270,7 +269,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.overflow.x = Overflow::Hidden;
+        self.style_mut().overflow.x = Overflow::Hidden;
         self
     }
 
@@ -278,7 +277,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.overflow.x = Overflow::Scroll;
+        self.style_mut().overflow.x = Overflow::Scroll;
         self
     }
 
@@ -286,7 +285,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.overflow.y = Overflow::Visible;
+        self.style_mut().overflow.y = Overflow::Visible;
         self
     }
 
@@ -294,7 +293,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.overflow.y = Overflow::Hidden;
+        self.style_mut().overflow.y = Overflow::Hidden;
         self
     }
 
@@ -302,7 +301,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.overflow.y = Overflow::Scroll;
+        self.style_mut().overflow.y = Overflow::Scroll;
         self
     }
 
@@ -312,7 +311,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.position = Position::Relative;
+        self.style_mut().position = Position::Relative;
         self
     }
 
@@ -320,7 +319,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.position = Position::Absolute;
+        self.style_mut().position = Position::Absolute;
 
         self
     }
@@ -330,10 +329,10 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.inset.top = length;
-        self.metadata().style.inset.right = length;
-        self.metadata().style.inset.bottom = length;
-        self.metadata().style.inset.left = length;
+        self.style_mut().inset.top = length;
+        self.style_mut().inset.right = length;
+        self.style_mut().inset.bottom = length;
+        self.style_mut().inset.left = length;
         self
     }
 
@@ -341,7 +340,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.size.width = width.into();
+        self.style_mut().size.width = width.into();
         self
     }
 
@@ -349,7 +348,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.size.width = Length::Auto;
+        self.style_mut().size.width = Length::Auto;
         self
     }
 
@@ -358,7 +357,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.size.width = length;
+        self.style_mut().size.width = length;
         self
     }
 
@@ -367,7 +366,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.min_size.width = length;
+        self.style_mut().min_size.width = length;
         self
     }
 
@@ -375,7 +374,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.size.height = height.into();
+        self.style_mut().size.height = height.into();
         self
     }
 
@@ -383,7 +382,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.size.height = Length::Auto;
+        self.style_mut().size.height = Length::Auto;
         self
     }
 
@@ -392,7 +391,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.size.height = height;
+        self.style_mut().size.height = height;
         self
     }
 
@@ -401,7 +400,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.min_size.height = length;
+        self.style_mut().min_size.height = length;
         self
     }
 
@@ -409,7 +408,7 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.fill = fill.into();
+        self.style_mut().fill = fill.into();
         self
     }
 
@@ -417,14 +416,15 @@ pub trait Element<V: 'static>: 'static {
     where
         Self: Sized,
     {
-        self.metadata().style.text_color = Some(color.into());
+        self.style_mut().text_color = Some(color.into());
         self
     }
 }
 
 // Object-safe counterpart of Element used by AnyElement to store elements as trait objects.
 trait ElementObject<V> {
-    fn metadata(&mut self) -> &mut ElementMetadata<V>;
+    fn style_mut(&mut self) -> &mut ElementStyle;
+    fn handlers_mut(&mut self) -> &mut Vec<EventHandler<V>>;
     fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>)
         -> Result<(NodeId, Box<dyn Any>)>;
     fn paint(
@@ -436,8 +436,12 @@ trait ElementObject<V> {
 }
 
 impl<V: 'static, E: Element<V>> ElementObject<V> for E {
-    fn metadata(&mut self) -> &mut ElementMetadata<V> {
-        Element::metadata(self)
+    fn style_mut(&mut self) -> &mut ElementStyle {
+        Element::style_mut(self)
+    }
+
+    fn handlers_mut(&mut self) -> &mut Vec<EventHandler<V>> {
+        Element::handlers_mut(self)
     }
 
     fn layout(
@@ -486,7 +490,7 @@ impl<V: 'static> AnyElement<V> {
     }
 
     pub fn push_text_style(&mut self, cx: &mut impl RenderContext) -> bool {
-        let text_style = self.element.metadata().style.text_style();
+        let text_style = self.element.style_mut().text_style();
         if let Some(text_style) = text_style {
             let mut current_text_style = cx.text_style();
             text_style.apply(&mut current_text_style);
@@ -512,7 +516,7 @@ impl<V: 'static> AnyElement<V> {
             from_element: element_layout.as_mut(),
         };
 
-        for event_handler in self.element.metadata().handlers.iter().cloned() {
+        for event_handler in self.element.handlers_mut().iter().cloned() {
             let EngineLayout { order, bounds } = layout.from_engine;
 
             let view_id = cx.view_id();
@@ -547,8 +551,12 @@ impl<V: 'static> AnyElement<V> {
 impl<V: 'static> Element<V> for AnyElement<V> {
     type Layout = ();
 
-    fn metadata(&mut self) -> &mut ElementMetadata<V> {
-        self.element.metadata()
+    fn style_mut(&mut self) -> &mut ElementStyle {
+        self.element.style_mut()
+    }
+
+    fn handlers_mut(&mut self) -> &mut Vec<EventHandler<V>> {
+        self.element.handlers_mut()
     }
 
     fn layout(

crates/gpui/playground/src/div.rs → crates/gpui/playground/src/frame.rs 🔗

@@ -1,5 +1,8 @@
-use crate::element::{
-    AnyElement, Element, ElementMetadata, IntoElement, Layout, LayoutContext, NodeId, PaintContext,
+use crate::{
+    element::{
+        AnyElement, Element, EventHandler, IntoElement, Layout, LayoutContext, NodeId, PaintContext,
+    },
+    style::ElementStyle,
 };
 use anyhow::{anyhow, Result};
 use gpui::LayoutNodeId;
@@ -7,23 +10,29 @@ use playground_macros::IntoElement;
 
 #[derive(IntoElement)]
 #[element_crate = "crate"]
-pub struct Div<V: 'static> {
-    metadata: ElementMetadata<V>,
+pub struct Frame<V: 'static> {
+    style: ElementStyle,
+    handlers: Vec<EventHandler<V>>,
     children: Vec<AnyElement<V>>,
 }
 
-pub fn div<V>() -> Div<V> {
-    Div {
-        metadata: ElementMetadata::default(),
+pub fn frame<V>() -> Frame<V> {
+    Frame {
+        style: ElementStyle::default(),
+        handlers: Vec::new(),
         children: Vec::new(),
     }
 }
 
-impl<V: 'static> Element<V> for Div<V> {
+impl<V: 'static> Element<V> for Frame<V> {
     type Layout = ();
 
-    fn metadata(&mut self) -> &mut ElementMetadata<V> {
-        &mut self.metadata
+    fn style_mut(&mut self) -> &mut ElementStyle {
+        &mut self.style
+    }
+
+    fn handlers_mut(&mut self) -> &mut Vec<EventHandler<V>> {
+        &mut self.handlers
     }
 
     fn layout(
@@ -41,10 +50,7 @@ impl<V: 'static> Element<V> for Div<V> {
         let node_id = cx
             .layout_engine()
             .ok_or_else(|| anyhow!("no layout engine"))?
-            .add_node(
-                self.metadata.style.to_taffy(rem_size),
-                child_layout_node_ids,
-            )?;
+            .add_node(self.style.to_taffy(rem_size), child_layout_node_ids)?;
 
         Ok((node_id, ()))
     }
@@ -52,7 +58,7 @@ impl<V: 'static> Element<V> for Div<V> {
     fn paint(&mut self, layout: Layout<()>, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
         cx.scene.push_quad(gpui::scene::Quad {
             bounds: layout.from_engine.bounds,
-            background: self.metadata.style.fill.color().map(Into::into),
+            background: self.style.fill.color().map(Into::into),
             border: Default::default(),
             corner_radii: Default::default(),
         });
@@ -64,7 +70,7 @@ impl<V: 'static> Element<V> for Div<V> {
     }
 }
 
-impl<V: 'static> Div<V> {
+impl<V: 'static> Frame<V> {
     pub fn child(mut self, child: impl IntoElement<V>) -> Self {
         self.children.push(child.into_any_element());
         self

crates/gpui/playground/src/playground.rs 🔗

@@ -1,11 +1,11 @@
 #![allow(dead_code, unused_variables)]
 use color::black;
 use components::button;
-use div::div;
 use element::Element;
+use frame::frame;
 use gpui::{
     geometry::{rect::RectF, vector::vec2f},
-    platform::WindowOptions,
+    platform::{MouseButton, WindowOptions},
 };
 use log::LevelFilter;
 use simplelog::SimpleLogger;
@@ -16,8 +16,8 @@ use view::view;
 mod adapter;
 mod color;
 mod components;
-mod div;
 mod element;
+mod frame;
 mod paint_context;
 mod style;
 mod text;
@@ -44,7 +44,7 @@ fn main() {
 }
 
 fn playground<V: 'static>(theme: &ThemeColors) -> impl Element<V> {
-    div()
+    frame()
         .text_color(black())
         .h_full()
         .w_half()

crates/gpui/playground/src/style.rs 🔗

@@ -1,20 +1,11 @@
 use crate::color::Hsla;
 use gpui::geometry::{DefinedLength, Edges, Length, Point, Size};
-use playground_macros::Overrides;
 pub use taffy::style::{
     AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, JustifyContent,
     Overflow, Position,
 };
 
-pub trait Overrides {
-    type Base;
-
-    fn is_some(&self) -> bool;
-    fn apply(&self, base: &mut Self::Base);
-}
-
-#[derive(Clone, Overrides)]
-#[overrides_crate = "crate"]
+#[derive(Clone)]
 pub struct ElementStyle {
     /// What layout strategy should be used?
     pub display: Display,

crates/gpui/playground/src/text.rs 🔗

@@ -1,4 +1,4 @@
-use crate::element::{Element, ElementMetadata, IntoElement};
+use crate::element::{Element, ElementMetadata, EventHandler, IntoElement};
 use gpui::{geometry::Size, text_layout::LineLayout, RenderContext};
 use parking_lot::Mutex;
 use std::sync::Arc;
@@ -22,8 +22,8 @@ pub struct Text<V> {
 impl<V: 'static> Element<V> for Text<V> {
     type Layout = Arc<Mutex<Option<TextLayout>>>;
 
-    fn metadata(&mut self) -> &mut crate::element::ElementMetadata<V> {
-        &mut self.metadata
+    fn style_mut(&mut self) -> &mut crate::style::ElementStyle {
+        &mut self.metadata.style
     }
 
     fn layout(
@@ -91,6 +91,10 @@ impl<V: 'static> Element<V> for Text<V> {
         );
         Ok(())
     }
+
+    fn handlers_mut(&mut self) -> &mut Vec<EventHandler<V>> {
+        &mut self.metadata.handlers
+    }
 }
 
 pub struct TextLayout {

crates/gpui/playground_macros/src/derive_element.rs 🔗

@@ -79,8 +79,12 @@ pub fn derive_element(input: TokenStream) -> TokenStream {
         {
             type Layout = #crate_name::element::AnyElement<V>;
 
-            fn metadata(&mut self) -> &mut #crate_name::element::ElementMetadata<V> {
-                &mut self.metadata
+            fn style_mut(&mut self) -> &mut #crate_name::style::ElementStyle {
+                &mut self.metadata.style
+            }
+
+            fn handlers_mut(&mut self) -> &mut Vec<#crate_name::element::EventHandler<V>> {
+                &mut self.metadata.handlers
             }
 
             fn layout(

crates/gpui/playground_macros/src/derive_overrides.rs 🔗

@@ -1,119 +0,0 @@
-extern crate proc_macro;
-use proc_macro::TokenStream;
-use quote::{format_ident, quote};
-use syn::{parse_macro_input, Data, DeriveInput, Fields, Lit, Meta};
-
-/// When deriving Overrides on a struct Foo, builds a new struct FooOverrides
-/// that implements the Overrides trait so it can be applied to Foo.
-pub fn derive_overrides(input: TokenStream) -> TokenStream {
-    let input = parse_macro_input!(input as DeriveInput);
-
-    let crate_name: String = input
-        .attrs
-        .iter()
-        .find_map(|attr| {
-            if attr.path.is_ident("overrides_crate") {
-                match attr.parse_meta() {
-                    Ok(Meta::NameValue(nv)) => {
-                        if let Lit::Str(s) = nv.lit {
-                            Some(s.value())
-                        } else {
-                            None
-                        }
-                    }
-                    _ => None,
-                }
-            } else {
-                None
-            }
-        })
-        .unwrap_or_else(|| String::from("playground"));
-    let crate_name = format_ident!("{}", crate_name);
-
-    let ident = input.ident;
-    let new_ident = syn::Ident::new(&format!("{}Overrides", ident), ident.span());
-    let data = match input.data {
-        Data::Struct(s) => s,
-        _ => panic!("Override can only be derived for structs"),
-    };
-
-    let fields = match data.fields {
-        Fields::Named(fields) => fields.named,
-        _ => panic!("Override can only be derived for structs with named fields"),
-    };
-
-    let new_fields = fields
-        .iter()
-        .map(|f| {
-            let name = &f.ident;
-            let ty = &f.ty;
-
-            if let syn::Type::Path(typepath) = ty {
-                if typepath.path.segments.last().unwrap().ident == "Option" {
-                    return quote! { #name: #ty };
-                }
-            }
-            quote! { #name: Option<#ty> }
-        })
-        .collect::<Vec<_>>();
-
-    let names = fields.iter().map(|f| &f.ident);
-    let is_some_implementation = names.clone().map(|name| {
-        quote! {
-            self.#name.is_some()
-        }
-    });
-
-    let apply_implementation = fields.iter().map(|f| {
-        let name = &f.ident;
-        let ty = &f.ty;
-
-        if let syn::Type::Path(typepath) = ty {
-            if typepath.path.segments.last().unwrap().ident == "Option" {
-                return quote! {
-                    base.#name = self.#name.clone();
-                };
-            }
-        }
-
-        quote! {
-            if let Some(value) = &self.#name {
-                base.#name = value.clone();
-            }
-        }
-    });
-
-    let default_implementation = names.map(|name| {
-        quote! {
-            #name: None,
-        }
-    });
-
-    let expanded = quote! {
-        pub struct #new_ident {
-            #(#new_fields,)*
-        }
-
-        impl #crate_name::style::Overrides for #new_ident {
-            type Base = #ident;
-
-            fn is_some(&self) -> bool {
-                #(#is_some_implementation)||*
-            }
-
-            fn apply(&self, base: &mut Self::Base) {
-                #(#apply_implementation)*
-            }
-        }
-
-        impl Default for #new_ident {
-            fn default() -> Self {
-                Self {
-                    #(#default_implementation)*
-                }
-            }
-        }
-    };
-
-    TokenStream::from(expanded)
-}

crates/gpui/playground_macros/src/playground_macros.rs 🔗

@@ -2,7 +2,6 @@ use proc_macro::TokenStream;
 
 mod derive_element;
 mod derive_into_element;
-mod derive_overrides;
 mod tailwind_lengths;
 
 #[proc_macro_derive(Element, attributes(element_crate))]
@@ -15,11 +14,6 @@ pub fn derive_into_element(input: TokenStream) -> TokenStream {
     derive_into_element::derive_into_element(input)
 }
 
-#[proc_macro_derive(Overrides, attributes(overrides_crate))]
-pub fn derive_overrides(input: TokenStream) -> TokenStream {
-    derive_overrides::derive_overrides(input)
-}
-
 #[proc_macro_attribute]
 pub fn tailwind_lengths(attr: TokenStream, item: TokenStream) -> TokenStream {
     tailwind_lengths::tailwind_lengths(attr, item)