Skip to content

Commit

Permalink
rethink code
Browse files Browse the repository at this point in the history
  • Loading branch information
vic1707 committed Sep 15, 2024
1 parent e8ebbb2 commit abc6d3d
Showing 1 changed file with 36 additions and 46 deletions.
82 changes: 36 additions & 46 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use deserialize_impl::DeserializeImpl;
use utils::tri;
/* Built-in imports */
extern crate alloc;
use alloc::{format, string::ToString};
use alloc::format;
/* Dependencies */
use quote::quote;
use syn::Data;
Expand All @@ -20,62 +20,52 @@ pub fn derive_deserialize_versioned(
input: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let derive_input: syn::DeriveInput = syn::parse_macro_input!(input);
let derive_attrs = derive_input.attrs.clone();
let data_kind = match derive_input.data {
Data::Enum(_) => "enum",
Data::Struct(_) => "struct",
Data::Union(_) => "union",

let Some(versioning_attr) = derive_input
.attrs
.iter()
.find(|meta| meta.path().is_ident("versioning"))
else {
return tri!(DeserializeImpl::try_from(derive_input)).into();
};
let data_name = derive_input.ident.to_string();
let mut deserialize_impl = tri!(DeserializeImpl::try_from(derive_input));

let Attributes {
versioning,
optimistic,
} = match derive_attrs
.iter()
.find(|meta| meta.path().is_ident("versioning"))
{
// if no `versioning` attribut found
// simply return the default serde derived impl.
None => return proc_macro::TokenStream::from(deserialize_impl),
Some(attr) => tri!(Attributes::try_from(attr)),
} = tri!(Attributes::try_from(versioning_attr));
let ds_ident = derive_input.ident.clone();
let ds_kind_name = match derive_input.data {
Data::Enum(_) => "enum",
Data::Struct(_) => "struct",
Data::Union(_) => "union",
};
let no_match_message =
format!("data did not match any version of {ds_kind_name} {ds_ident}.");

if optimistic {
let no_match_message = format!(
"data did not match any version of {data_kind} {data_name}"
);
tri!(deserialize_impl.replace_body(|de_stmts|
quote! {{
use _serde::__private::de::{Content, ContentRefDeserializer};
let __content = Content::deserialize(__deserializer)?;
let __deserializer = ContentRefDeserializer::<__D::Error>::new(&__content);

if let Ok(__ok) = { #(#de_stmts)* } {
return Ok(__ok)
}
let mut deserialize_impl = tri!(DeserializeImpl::try_from(derive_input));

tri!(deserialize_impl.replace_body(|de_stmts|{
let deserialization = if optimistic {
quote! {
if let Ok(__ok) = { #(#de_stmts)* } { return Ok(__ok) }
#versioning

return Err(
_serde::de::Error::custom(#no_match_message),
);
}}
));
} else {
tri!(deserialize_impl.replace_body(|de_stmts|
quote! {{
use _serde::__private::de::{Content, ContentRefDeserializer};
let __content = Content::deserialize(__deserializer)?;
let __deserializer = ContentRefDeserializer::<__D::Error>::new(&__content);

return Err(_serde::de::Error::custom(#no_match_message));
}
} else {
quote! {
#versioning

#(#de_stmts)*
}}
));
}
}
};

quote! {{
use _serde::__private::de::{Content, ContentRefDeserializer};
let __content = Content::deserialize(__deserializer)?;
let __deserializer = ContentRefDeserializer::<__D::Error>::new(&__content);

#deserialization
}}
}));

proc_macro::TokenStream::from(deserialize_impl)
}

0 comments on commit abc6d3d

Please sign in to comment.