use crate::parse::options::ParseOptions;
use proc_macro2::TokenStream;
use quote::quote;
pub fn expand(options: &ParseOptions) -> syn::Result<TokenStream> {
if !options.serde_as && !options.serialize_as && !options.deserialize_as {
return Ok(quote!());
}
let mut result = quote!();
if options.serde_as || options.serialize_as {
if !options.write {
return Err(syn::Error::new_spanned(
&options.ident,
"cannot use `serde_as` or `serialize_as` without `write`",
));
}
let source = &options.source;
let ident = &options.ident;
let (impl_generics, type_generics, where_clause) = options.generics.split_for_impl();
result.extend(quote! {
#[automatically_derived]
impl #impl_generics _serde::Serialize for #ident #type_generics #where_clause {
fn serialize<__S>(&self, serializer: __S) -> core::result::Result<__S::Ok, __S::Error>
where
__S: _serde::Serializer,
{
#source::serialize(&self.clone().into(), serializer)
}
}
});
}
if options.serde_as || options.deserialize_as {
let source = &options.source;
let ident = &options.ident;
let (impl_generics, type_generics, where_clause) = options.generics.split_for_impl();
result.extend(quote! {
#[automatically_derived]
impl<'de> #impl_generics _serde::Deserialize<'de> for #ident #type_generics #where_clause {
fn deserialize<__D>(deserializer: __D) -> core::result::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
#source::deserialize(deserializer)?
.parse_into()
.map_err(_serde::de::Error::custom)
}
}
});
}
Ok(result)
}