Skip to content

Commit

Permalink
feat: added automatic conversion methods for reactive types (#252)
Browse files Browse the repository at this point in the history
* chore: added ::new for intermediate type

* chore: Add From for intermediate

* Ran cargo fmt
  • Loading branch information
iRaiko authored Feb 2, 2023
1 parent fa62ebe commit bb36a4c
Showing 1 changed file with 40 additions and 1 deletion.
41 changes: 40 additions & 1 deletion packages/perseus-macro/src/rx_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ pub fn make_rx_impl(input: ReactiveStateDeriveInput) -> TokenStream {
// reactive `struct`s
let mut intermediate_fields = quote!();
let mut intermediate_field_makers = quote!();
let mut new_intermediate_field_makers = quote!();
let mut unrx_field_makers = quote!();
let mut suspense_commands = quote!();
let mut old_types = quote!();
for field in fields.iter() {
let old_ty = field.ty.to_token_stream();
let field_ident = field.ident.as_ref().unwrap(); // It's a `struct`, so this is defined
Expand All @@ -77,7 +79,10 @@ pub fn make_rx_impl(input: ReactiveStateDeriveInput) -> TokenStream {
for attr in field.attrs.iter() {
field_attrs.extend(attr.to_token_stream());
}

// Old for ::new implementation of intermediate type
old_types.extend(quote! {
#field_ident: #old_ty,
});
// Nested fields are left as-is, non-nested ones are wrapped in `RcSignal`s
if field.nested {
// Nested types should implement the necessary linking traits
Expand All @@ -86,6 +91,7 @@ pub fn make_rx_impl(input: ReactiveStateDeriveInput) -> TokenStream {
#field_vis #field_ident: <#old_ty as ::perseus::state::MakeRx>::Rx,
});
intermediate_field_makers.extend(quote! { #field_ident: self.#field_ident.make_rx(), });
new_intermediate_field_makers.extend(quote! { #field_ident: #field_ident.make_rx(), });
unrx_field_makers
.extend(quote! { #field_ident: self.#field_ident.clone().make_unrx(), });

Expand Down Expand Up @@ -118,6 +124,9 @@ pub fn make_rx_impl(input: ReactiveStateDeriveInput) -> TokenStream {
intermediate_field_makers.extend(
quote! { #field_ident: ::sycamore::prelude::create_rc_signal(self.#field_ident), },
);
new_intermediate_field_makers.extend(
quote! { #field_ident: ::sycamore::prelude::create_rc_signal(#field_ident), },
);
// All fields must be `Clone`
unrx_field_makers
.extend(quote! { #field_ident: (*self.#field_ident.get_untracked()).clone(), });
Expand Down Expand Up @@ -177,6 +186,36 @@ pub fn make_rx_impl(input: ReactiveStateDeriveInput) -> TokenStream {
#intermediate_fields
}

impl #intermediate_ident
{
fn new(#old_types) -> #intermediate_ident
{
use ::perseus::state::MakeRx;
#intermediate_ident
{
#new_intermediate_field_makers
}
}
}

impl From<#intermediate_ident> for #ident
{
fn from(value: #intermediate_ident) -> #ident
{
use ::perseus::state::MakeUnrx;
value.make_unrx()
}
}

impl From<#ident> for #intermediate_ident
{
fn from(value: #ident) -> #intermediate_ident
{
use ::perseus::state::MakeRx;
value.make_rx()
}
}

impl ::perseus::state::MakeRx for #ident {
type Rx = #intermediate_ident;
fn make_rx(self) -> Self::Rx {
Expand Down

0 comments on commit bb36a4c

Please sign in to comment.