Skip to content

Commit bb36a4c

Browse files
authored
feat: added automatic conversion methods for reactive types (#252)
* chore: added ::new for intermediate type * chore: Add From for intermediate * Ran cargo fmt
1 parent fa62ebe commit bb36a4c

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

packages/perseus-macro/src/rx_state.rs

+40-1
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@ pub fn make_rx_impl(input: ReactiveStateDeriveInput) -> TokenStream {
6767
// reactive `struct`s
6868
let mut intermediate_fields = quote!();
6969
let mut intermediate_field_makers = quote!();
70+
let mut new_intermediate_field_makers = quote!();
7071
let mut unrx_field_makers = quote!();
7172
let mut suspense_commands = quote!();
73+
let mut old_types = quote!();
7274
for field in fields.iter() {
7375
let old_ty = field.ty.to_token_stream();
7476
let field_ident = field.ident.as_ref().unwrap(); // It's a `struct`, so this is defined
@@ -77,7 +79,10 @@ pub fn make_rx_impl(input: ReactiveStateDeriveInput) -> TokenStream {
7779
for attr in field.attrs.iter() {
7880
field_attrs.extend(attr.to_token_stream());
7981
}
80-
82+
// Old for ::new implementation of intermediate type
83+
old_types.extend(quote! {
84+
#field_ident: #old_ty,
85+
});
8186
// Nested fields are left as-is, non-nested ones are wrapped in `RcSignal`s
8287
if field.nested {
8388
// Nested types should implement the necessary linking traits
@@ -86,6 +91,7 @@ pub fn make_rx_impl(input: ReactiveStateDeriveInput) -> TokenStream {
8691
#field_vis #field_ident: <#old_ty as ::perseus::state::MakeRx>::Rx,
8792
});
8893
intermediate_field_makers.extend(quote! { #field_ident: self.#field_ident.make_rx(), });
94+
new_intermediate_field_makers.extend(quote! { #field_ident: #field_ident.make_rx(), });
8995
unrx_field_makers
9096
.extend(quote! { #field_ident: self.#field_ident.clone().make_unrx(), });
9197

@@ -118,6 +124,9 @@ pub fn make_rx_impl(input: ReactiveStateDeriveInput) -> TokenStream {
118124
intermediate_field_makers.extend(
119125
quote! { #field_ident: ::sycamore::prelude::create_rc_signal(self.#field_ident), },
120126
);
127+
new_intermediate_field_makers.extend(
128+
quote! { #field_ident: ::sycamore::prelude::create_rc_signal(#field_ident), },
129+
);
121130
// All fields must be `Clone`
122131
unrx_field_makers
123132
.extend(quote! { #field_ident: (*self.#field_ident.get_untracked()).clone(), });
@@ -177,6 +186,36 @@ pub fn make_rx_impl(input: ReactiveStateDeriveInput) -> TokenStream {
177186
#intermediate_fields
178187
}
179188

189+
impl #intermediate_ident
190+
{
191+
fn new(#old_types) -> #intermediate_ident
192+
{
193+
use ::perseus::state::MakeRx;
194+
#intermediate_ident
195+
{
196+
#new_intermediate_field_makers
197+
}
198+
}
199+
}
200+
201+
impl From<#intermediate_ident> for #ident
202+
{
203+
fn from(value: #intermediate_ident) -> #ident
204+
{
205+
use ::perseus::state::MakeUnrx;
206+
value.make_unrx()
207+
}
208+
}
209+
210+
impl From<#ident> for #intermediate_ident
211+
{
212+
fn from(value: #ident) -> #intermediate_ident
213+
{
214+
use ::perseus::state::MakeRx;
215+
value.make_rx()
216+
}
217+
}
218+
180219
impl ::perseus::state::MakeRx for #ident {
181220
type Rx = #intermediate_ident;
182221
fn make_rx(self) -> Self::Rx {

0 commit comments

Comments
 (0)