Detailed changes
@@ -0,0 +1,54 @@
+use proc_macro::TokenStream;
+use quote::quote;
+use syn::{parse_macro_input, DeriveInput};
+
+pub fn derive_into_any_element(input: TokenStream) -> TokenStream {
+ let ast = parse_macro_input!(input as DeriveInput);
+ let name = &ast.ident;
+ let generics = &ast.generics;
+ let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+
+ let specified_view_type = ast
+ .attrs
+ .iter()
+ .find(|attr| attr.path.is_ident("element"))
+ .and_then(|attr| {
+ if let Ok(syn::Meta::List(meta_list)) = attr.parse_meta() {
+ meta_list.nested.iter().find_map(|nested| {
+ if let syn::NestedMeta::Meta(syn::Meta::NameValue(nv)) = nested {
+ if nv.path.is_ident("view_type") {
+ if let syn::Lit::Str(lit_str) = &nv.lit {
+ return Some(
+ lit_str
+ .parse::<syn::Ident>()
+ .expect("Failed to parse view_type"),
+ );
+ }
+ }
+ }
+ None
+ })
+ } else {
+ None
+ }
+ });
+
+ let view_type = specified_view_type.unwrap_or_else(|| {
+ if let Some(syn::GenericParam::Type(type_param)) = generics.params.first() {
+ type_param.ident.clone()
+ } else {
+ panic!("Expected first type parameter");
+ }
+ });
+
+ let expanded = quote! {
+ impl #impl_generics gpui2::IntoAnyElement<#view_type> for #name #ty_generics #where_clause {
+ fn into_any(self) -> gpui2::AnyElement<#view_type> {
+ (move |view_state: &mut #view_type, cx: &mut gpui2::ViewContext<'_, '_, #view_type>| self.render(view_state, cx))
+ .into_any()
+ }
+ }
+ };
+
+ TokenStream::from(expanded)
+}
@@ -1,6 +1,7 @@
use proc_macro::TokenStream;
mod derive_element;
+mod derive_into_any_element;
mod style_helpers;
mod test;
@@ -14,6 +15,11 @@ pub fn derive_element(input: TokenStream) -> TokenStream {
derive_element::derive_element(input)
}
+#[proc_macro_derive(IntoAnyElement, attributes(element))]
+pub fn derive_into_any_element(input: TokenStream) -> TokenStream {
+ derive_into_any_element::derive_into_any_element(input)
+}
+
#[proc_macro_attribute]
pub fn test(args: TokenStream, function: TokenStream) -> TokenStream {
test::test(args, function)
@@ -12,6 +12,7 @@ pub enum SplitDirection {
Vertical,
}
+#[derive(IntoAnyElement)]
pub struct Pane<V: 'static> {
id: ElementId,
size: Size<Length>,
@@ -19,12 +20,12 @@ pub struct Pane<V: 'static> {
children: SmallVec<[AnyElement<V>; 2]>,
}
-impl<V: 'static> IntoAnyElement<V> for Pane<V> {
- fn into_any(self) -> AnyElement<V> {
- (move |view_state: &mut V, cx: &mut ViewContext<'_, '_, V>| self.render(view_state, cx))
- .into_any()
- }
-}
+// impl<V: 'static> IntoAnyElement<V> for Pane<V> {
+// fn into_any(self) -> AnyElement<V> {
+// (move |view_state: &mut V, cx: &mut ViewContext<'_, '_, V>| self.render(view_state, cx))
+// .into_any()
+// }
+// }
impl<V: 'static> Pane<V> {
pub fn new(id: impl Into<ElementId>, size: Size<Length>) -> Self {
@@ -28,14 +28,23 @@ impl Default for ToolGroup {
}
}
-#[derive(Element)]
-#[element(view_state = "Workspace")]
+#[derive(IntoAnyElement)]
+#[element(view_type = "Workspace")]
pub struct StatusBar {
left_tools: Option<ToolGroup>,
right_tools: Option<ToolGroup>,
bottom_tools: Option<ToolGroup>,
}
+// impl IntoAnyElement<Workspace> for StatusBar {
+// fn into_any(self) -> gpui2::AnyElement<Workspace> {
+// (move |workspace: &mut Workspace, cx: &mut ViewContext<'_, '_, Workspace>| {
+// self.render(workspace, cx)
+// })
+// .into_any()
+// }
+// }
+
impl StatusBar {
pub fn new() -> Self {
Self {
@@ -83,7 +92,7 @@ impl StatusBar {
}
fn render(
- &mut self,
+ self,
view: &mut Workspace,
cx: &mut ViewContext<Workspace>,
) -> impl IntoAnyElement<Workspace> {