Support for serde::Deserialize
This commit is contained in:
1 parent
46dac98882
commit
1cdef76c2e
2 files changed
+135
-39
No files matched your search
+128
-36
@@ -9,7 +9,7 @@ use syn::{Data, DataEnum, DeriveInput};
|
|||||||
|
|
||||||
use error::{MacroError, MacroResult};
|
use error::{MacroError, MacroResult};
|
||||||
|
|
||||||
use crate::enums::{Variant, VariantType};
|
use crate::enums::{Variant, VariantType, Enum};
|
||||||
|
|
||||||
mod enums;
|
mod enums;
|
||||||
mod attribute;
|
mod attribute;
|
||||||
@@ -131,12 +131,12 @@ fn gen_unscribe_impl<F, G, E>(
|
|||||||
trait_return_type: TokenStream2,
|
trait_return_type: TokenStream2,
|
||||||
named_fn: F,
|
named_fn: F,
|
||||||
other_fn: G,
|
other_fn: G,
|
||||||
other_missing_fn: E
|
other_missing_fn: E,
|
||||||
) -> TokenStream
|
) -> TokenStream
|
||||||
where
|
where
|
||||||
F: Fn(TokenStream2) -> TokenStream2,
|
F: Fn(TokenStream2) -> TokenStream2,
|
||||||
G: Fn(TokenStream2) -> TokenStream2,
|
G: Fn(TokenStream2) -> TokenStream2,
|
||||||
E: Fn(&Ident) -> MacroResult<TokenStream2>
|
E: Fn(&Ident) -> MacroResult<TokenStream2>
|
||||||
{
|
{
|
||||||
let input: DeriveInput = syn::parse(input)
|
let input: DeriveInput = syn::parse(input)
|
||||||
.expect("failed to parse input");
|
.expect("failed to parse input");
|
||||||
@@ -146,12 +146,38 @@ where
|
|||||||
|
|
||||||
let enum_ident = &input.ident;
|
let enum_ident = &input.ident;
|
||||||
|
|
||||||
|
let to_unscribe_ident = quote! { __enumscribe_to_unscribe };
|
||||||
|
|
||||||
|
let main_match = proc_try!(gen_unscribe_match(
|
||||||
|
enum_ident, &parsed_enum, &to_unscribe_ident, named_fn, other_fn, other_missing_fn
|
||||||
|
));
|
||||||
|
|
||||||
|
(quote! {
|
||||||
|
impl #trait_ident for #enum_ident {
|
||||||
|
fn #trait_fn_name(#to_unscribe_ident: &str) -> #trait_return_type {
|
||||||
|
#main_match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_unscribe_match<F, G, E>(
|
||||||
|
enum_ident: &Ident,
|
||||||
|
parsed_enum: &Enum,
|
||||||
|
match_against: &TokenStream2,
|
||||||
|
named_fn: F,
|
||||||
|
other_fn: G,
|
||||||
|
other_missing_fn: E,
|
||||||
|
) -> MacroResult<TokenStream2>
|
||||||
|
where
|
||||||
|
F: Fn(TokenStream2) -> TokenStream2,
|
||||||
|
G: Fn(TokenStream2) -> TokenStream2,
|
||||||
|
E: Fn(&Ident) -> MacroResult<TokenStream2>
|
||||||
|
{
|
||||||
let mut other_arm = None;
|
let mut other_arm = None;
|
||||||
let mut case_sensitive_arms = Vec::new();
|
let mut case_sensitive_arms = Vec::new();
|
||||||
let mut case_insensitive_arms = Vec::new();
|
let mut case_insensitive_arms = Vec::new();
|
||||||
|
|
||||||
let to_unscribe_ident = quote! { __enumscribe_to_unscribe };
|
|
||||||
|
|
||||||
for variant in parsed_enum.variants.iter() {
|
for variant in parsed_enum.variants.iter() {
|
||||||
let variant_ident = &variant.data.ident;
|
let variant_ident = &variant.data.ident;
|
||||||
|
|
||||||
@@ -178,7 +204,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
VariantType::Other { field_name } => {
|
VariantType::Other { field_name } => {
|
||||||
let unscribe_value = quote! { <_ as ::std::convert::Into<_>>::into(#to_unscribe_ident) };
|
let unscribe_value = quote! { <_ as ::std::convert::Into<_>>::into(#match_against) };
|
||||||
|
|
||||||
let constructed_variant = match field_name {
|
let constructed_variant = match field_name {
|
||||||
None => quote! {
|
None => quote! {
|
||||||
@@ -198,14 +224,14 @@ where
|
|||||||
|
|
||||||
let other_arm = match other_arm {
|
let other_arm = match other_arm {
|
||||||
Some(other_arm) => other_arm,
|
Some(other_arm) => other_arm,
|
||||||
None => proc_try!(other_missing_fn(enum_ident))
|
None => other_missing_fn(enum_ident)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let case_insensitive_match = if case_insensitive_arms.is_empty() {
|
let case_insensitive_match = if case_insensitive_arms.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
let __enumscribe_unscribe_lowercase = #to_unscribe_ident.to_lowercase();
|
let __enumscribe_unscribe_lowercase = #match_against.to_lowercase();
|
||||||
match __enumscribe_unscribe_lowercase.as_str() {
|
match __enumscribe_unscribe_lowercase.as_str() {
|
||||||
#(#case_insensitive_arms,)*
|
#(#case_insensitive_arms,)*
|
||||||
#other_arm,
|
#other_arm,
|
||||||
@@ -215,13 +241,13 @@ where
|
|||||||
|
|
||||||
let main_match = match (case_sensitive_arms.is_empty(), case_insensitive_match) {
|
let main_match = match (case_sensitive_arms.is_empty(), case_insensitive_match) {
|
||||||
(true, None) => quote! {
|
(true, None) => quote! {
|
||||||
match #to_unscribe_ident {
|
match #match_against {
|
||||||
#other_arm,
|
#other_arm,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
(false, None) => quote! {
|
(false, None) => quote! {
|
||||||
match #to_unscribe_ident {
|
match #match_against {
|
||||||
#(#case_sensitive_arms,)*
|
#(#case_sensitive_arms,)*
|
||||||
#other_arm,
|
#other_arm,
|
||||||
}
|
}
|
||||||
@@ -229,45 +255,42 @@ where
|
|||||||
|
|
||||||
(true, Some(case_insensitive_match)) => {
|
(true, Some(case_insensitive_match)) => {
|
||||||
case_insensitive_match
|
case_insensitive_match
|
||||||
},
|
}
|
||||||
|
|
||||||
(false, Some(case_insensitive_match)) => quote! {
|
(false, Some(case_insensitive_match)) => quote! {
|
||||||
match #to_unscribe_ident {
|
match #match_against {
|
||||||
#(#case_sensitive_arms,)*
|
#(#case_sensitive_arms,)*
|
||||||
_ => { #case_insensitive_match },
|
_ => { #case_insensitive_match },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(quote! {
|
Ok(main_match)
|
||||||
impl #trait_ident for #enum_ident {
|
|
||||||
fn #trait_fn_name(#to_unscribe_ident: &str) -> #trait_return_type {
|
|
||||||
#main_match
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(ScribeStaticStr, attributes(enumscribe))]
|
#[proc_macro_derive(ScribeStaticStr, attributes(enumscribe))]
|
||||||
pub fn derive_scribe_static_str(input: TokenStream) -> TokenStream {
|
pub fn derive_scribe_static_str(input: TokenStream) -> TokenStream {
|
||||||
gen_scribe_impl(
|
gen_scribe_impl(
|
||||||
input,
|
input,
|
||||||
|
|
||||||
quote! { ::enumscribe::ScribeStaticStr },
|
quote! { ::enumscribe::ScribeStaticStr },
|
||||||
quote! { &'static str },
|
quote! { &'static str },
|
||||||
|
|
||||||
|_, _, name| Ok(quote! { #name }),
|
|_, _, name| Ok(quote! { #name }),
|
||||||
|
|
||||||
|variant, enum_ident, _| Err(MacroError::new(format!(
|
|variant, enum_ident, _| Err(MacroError::new(format!(
|
||||||
"cannot derive ScribeStaticStr for {} because the variant {} is marked as {}, so \
|
"cannot derive ScribeStaticStr for {} because the variant {} is marked as {}, so \
|
||||||
there is no &'static str associated with it\n\
|
there is no &'static str associated with it\n\
|
||||||
hint: try deriving ScribeCowStr instead",
|
hint: try deriving ScribeCowStr instead",
|
||||||
enum_ident.to_string(), variant.data.ident.to_string(), OTHER
|
enum_ident, variant.data.ident, OTHER
|
||||||
), variant.span)),
|
), variant.span)),
|
||||||
|
|
||||||
|variant, enum_ident| MacroError::new(format!(
|
|variant, enum_ident| MacroError::new(format!(
|
||||||
"cannot derive ScribeStaticStr for {} because the variant {} is marked as {}\n\
|
"cannot derive ScribeStaticStr for {} because the variant {} is marked as {}\n\
|
||||||
explanation: since {} is ignored, it cannot be guaranteed that the enum can \
|
explanation: since {} is ignored, it cannot be guaranteed that the enum can \
|
||||||
always be successfully converted to a String\n\
|
always be successfully converted to a String\n\
|
||||||
hint: try deriving TryScribeStaticStr instead",
|
hint: try deriving TryScribeStaticStr instead",
|
||||||
enum_ident.to_string(), variant.data.ident.to_string(), IGNORE,
|
enum_ident, variant.data.ident, IGNORE, variant.data.ident
|
||||||
variant.data.ident.to_string(),
|
|
||||||
), variant.span),
|
), variant.span),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -276,17 +299,21 @@ pub fn derive_scribe_static_str(input: TokenStream) -> TokenStream {
|
|||||||
pub fn derive_try_scribe_static_str(input: TokenStream) -> TokenStream {
|
pub fn derive_try_scribe_static_str(input: TokenStream) -> TokenStream {
|
||||||
gen_try_scribe_impl(
|
gen_try_scribe_impl(
|
||||||
input,
|
input,
|
||||||
|
|
||||||
quote! { ::enumscribe::TryScribeStaticStr },
|
quote! { ::enumscribe::TryScribeStaticStr },
|
||||||
quote! { ::std::option::Option<&'static str> },
|
quote! { ::std::option::Option<&'static str> },
|
||||||
|
|
||||||
|_, _, name| Ok(quote! {
|
|_, _, name| Ok(quote! {
|
||||||
::std::option::Option::Some(#name)
|
::std::option::Option::Some(#name)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|variant, enum_ident, _| Err(MacroError::new(format!(
|
|variant, enum_ident, _| Err(MacroError::new(format!(
|
||||||
"cannot derive TryScribeStaticStr for {} because the variant {} is marked as {}, so \
|
"cannot derive TryScribeStaticStr for {} because the variant {} is marked as {}, so \
|
||||||
there is no &'static str associated with it\n\
|
there is no &'static str associated with it\n\
|
||||||
hint: try deriving TryScribeCowStr instead",
|
hint: try deriving TryScribeCowStr instead",
|
||||||
enum_ident.to_string(), variant.data.ident.to_string(), OTHER
|
enum_ident, variant.data.ident, OTHER
|
||||||
), variant.span)),
|
), variant.span)),
|
||||||
|
|
||||||
quote! { ::std::option::Option::None },
|
quote! { ::std::option::Option::None },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -295,21 +322,24 @@ pub fn derive_try_scribe_static_str(input: TokenStream) -> TokenStream {
|
|||||||
pub fn derive_scribe_string(input: TokenStream) -> TokenStream {
|
pub fn derive_scribe_string(input: TokenStream) -> TokenStream {
|
||||||
gen_scribe_impl(
|
gen_scribe_impl(
|
||||||
input,
|
input,
|
||||||
|
|
||||||
quote! { ::enumscribe::ScribeString },
|
quote! { ::enumscribe::ScribeString },
|
||||||
quote! { ::std::string::String },
|
quote! { ::std::string::String },
|
||||||
|
|
||||||
|_, _, name| Ok(quote! {
|
|_, _, name| Ok(quote! {
|
||||||
<_ as ::std::borrow::ToOwned>::to_owned(#name)
|
<_ as ::std::borrow::ToOwned>::to_owned(#name)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|_, _, field| Ok(quote! {
|
|_, _, field| Ok(quote! {
|
||||||
<_ as ::std::convert::Into<::std::string::String>>::into(#field)
|
<_ as ::std::convert::Into<::std::string::String>>::into(#field)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|variant, enum_ident| MacroError::new(format!(
|
|variant, enum_ident| MacroError::new(format!(
|
||||||
"cannot derive ScribeString for {} because the variant {} is marked as {}\n\
|
"cannot derive ScribeString for {} because the variant {} is marked as {}\n\
|
||||||
explanation: since {} is ignored, it cannot be guaranteed that the enum can \
|
explanation: since {} is ignored, it cannot be guaranteed that the enum can \
|
||||||
always be successfully converted to a String\n\
|
always be successfully converted to a String\n\
|
||||||
hint: try deriving TryScribeString instead",
|
hint: try deriving TryScribeString instead",
|
||||||
enum_ident.to_string(), variant.data.ident.to_string(), IGNORE,
|
enum_ident, variant.data.ident, IGNORE, variant.data.ident
|
||||||
variant.data.ident.to_string(),
|
|
||||||
), variant.span),
|
), variant.span),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -318,18 +348,22 @@ pub fn derive_scribe_string(input: TokenStream) -> TokenStream {
|
|||||||
pub fn derive_try_scribe_string(input: TokenStream) -> TokenStream {
|
pub fn derive_try_scribe_string(input: TokenStream) -> TokenStream {
|
||||||
gen_try_scribe_impl(
|
gen_try_scribe_impl(
|
||||||
input,
|
input,
|
||||||
|
|
||||||
quote! { ::enumscribe::TryScribeString },
|
quote! { ::enumscribe::TryScribeString },
|
||||||
quote! { ::std::option::Option<::std::string::String> },
|
quote! { ::std::option::Option<::std::string::String> },
|
||||||
|
|
||||||
|_, _, name| Ok(quote! {
|
|_, _, name| Ok(quote! {
|
||||||
::std::option::Option::Some(
|
::std::option::Option::Some(
|
||||||
<_ as ::std::borrow::ToOwned>::to_owned(#name)
|
<_ as ::std::borrow::ToOwned>::to_owned(#name)
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|_, _, field| Ok(quote! {
|
|_, _, field| Ok(quote! {
|
||||||
::std::option::Option::Some(
|
::std::option::Option::Some(
|
||||||
<_ as ::std::convert::Into<::std::string::String>>::into(#field)
|
<_ as ::std::convert::Into<::std::string::String>>::into(#field)
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
quote! { ::std::option::Option::None },
|
quote! { ::std::option::Option::None },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -338,23 +372,26 @@ pub fn derive_try_scribe_string(input: TokenStream) -> TokenStream {
|
|||||||
pub fn derive_scribe_cow_str(input: TokenStream) -> TokenStream {
|
pub fn derive_scribe_cow_str(input: TokenStream) -> TokenStream {
|
||||||
gen_scribe_impl(
|
gen_scribe_impl(
|
||||||
input,
|
input,
|
||||||
|
|
||||||
quote! { ::enumscribe::ScribeCowStr },
|
quote! { ::enumscribe::ScribeCowStr },
|
||||||
quote! { ::std::borrow::Cow<'static, str> },
|
quote! { ::std::borrow::Cow<'static, str> },
|
||||||
|
|
||||||
|_, _, name| Ok(quote! {
|
|_, _, name| Ok(quote! {
|
||||||
::std::borrow::Cow::Borrowed(#name)
|
::std::borrow::Cow::Borrowed(#name)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|_, _, field| Ok(quote! {
|
|_, _, field| Ok(quote! {
|
||||||
::std::borrow::Cow::Owned(
|
::std::borrow::Cow::Owned(
|
||||||
<_ as ::std::convert::Into<::std::string::String>>::into(#field)
|
<_ as ::std::convert::Into<::std::string::String>>::into(#field)
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|variant, enum_ident| MacroError::new(format!(
|
|variant, enum_ident| MacroError::new(format!(
|
||||||
"cannot derive ScribeCowStr for {} because the variant {} is marked as {}\n\
|
"cannot derive ScribeCowStr for {} because the variant {} is marked as {}\n\
|
||||||
explanation: since {} is ignored, it cannot be guaranteed that the enum can \
|
explanation: since {} is ignored, it cannot be guaranteed that the enum can \
|
||||||
always be successfully converted to a String\n\
|
always be successfully converted to a String\n\
|
||||||
hint: try deriving TryScribeCowStr instead",
|
hint: try deriving TryScribeCowStr instead",
|
||||||
enum_ident.to_string(), variant.data.ident.to_string(), IGNORE,
|
enum_ident, variant.data.ident, IGNORE, variant.data.ident
|
||||||
variant.data.ident.to_string(),
|
|
||||||
), variant.span),
|
), variant.span),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -363,13 +400,16 @@ pub fn derive_scribe_cow_str(input: TokenStream) -> TokenStream {
|
|||||||
pub fn derive_try_scribe_cow_str(input: TokenStream) -> TokenStream {
|
pub fn derive_try_scribe_cow_str(input: TokenStream) -> TokenStream {
|
||||||
gen_try_scribe_impl(
|
gen_try_scribe_impl(
|
||||||
input,
|
input,
|
||||||
|
|
||||||
quote! { ::enumscribe::TryScribeCowStr },
|
quote! { ::enumscribe::TryScribeCowStr },
|
||||||
quote! { ::std::option::Option<::std::borrow::Cow<'static, str>> },
|
quote! { ::std::option::Option<::std::borrow::Cow<'static, str>> },
|
||||||
|
|
||||||
|_, _, name| Ok(quote! {
|
|_, _, name| Ok(quote! {
|
||||||
::std::option::Option::Some(
|
::std::option::Option::Some(
|
||||||
::std::borrow::Cow::Borrowed(#name)
|
::std::borrow::Cow::Borrowed(#name)
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|_, _, field| Ok(quote! {
|
|_, _, field| Ok(quote! {
|
||||||
::std::option::Option::Some(
|
::std::option::Option::Some(
|
||||||
::std::borrow::Cow::Owned(
|
::std::borrow::Cow::Owned(
|
||||||
@@ -377,6 +417,7 @@ pub fn derive_try_scribe_cow_str(input: TokenStream) -> TokenStream {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
quote! { ::std::option::Option::None },
|
quote! { ::std::option::Option::None },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -399,8 +440,8 @@ pub fn derive_unscribe(input: TokenStream) -> TokenStream {
|
|||||||
explanation: since there is no {} variant, it cannot be guaranteed that every string \
|
explanation: since there is no {} variant, it cannot be guaranteed that every string \
|
||||||
can be successfully converted to a variant of {}\n\
|
can be successfully converted to a variant of {}\n\
|
||||||
hint: either introduce an {} variant, or try deriving TryUnscribe instead",
|
hint: either introduce an {} variant, or try deriving TryUnscribe instead",
|
||||||
enum_ident.to_string(), OTHER, OTHER, enum_ident.to_string(), OTHER
|
enum_ident, OTHER, OTHER, enum_ident, OTHER
|
||||||
), enum_ident.span()))
|
), enum_ident.span())),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,7 +458,7 @@ pub fn derive_try_unscribe(input: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
|constructed_other_variant| quote! { ::std::option::Option::Some(#constructed_other_variant) },
|
|constructed_other_variant| quote! { ::std::option::Option::Some(#constructed_other_variant) },
|
||||||
|
|
||||||
|_| Ok(quote! { _ => ::std::option::Option::None })
|
|_| Ok(quote! { _ => ::std::option::Option::None }),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,7 +489,7 @@ pub fn derive_enum_serialize(input: TokenStream) -> TokenStream {
|
|||||||
#enum_ident::#variant_ident #constructor_tokens =>
|
#enum_ident::#variant_ident #constructor_tokens =>
|
||||||
#serializer_ident.serialize_str(#name)
|
#serializer_ident.serialize_str(#name)
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
|
|
||||||
VariantType::Other { field_name } => {
|
VariantType::Other { field_name } => {
|
||||||
match field_name {
|
match field_name {
|
||||||
@@ -457,7 +498,7 @@ pub fn derive_enum_serialize(input: TokenStream) -> TokenStream {
|
|||||||
#enum_ident::#variant_ident { #field_name } =>
|
#enum_ident::#variant_ident { #field_name } =>
|
||||||
#serializer_ident.serialize_str(&#field_name)
|
#serializer_ident.serialize_str(&#field_name)
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
None => {
|
None => {
|
||||||
let field_name = quote! { __enumscribe_other_inner };
|
let field_name = quote! { __enumscribe_other_inner };
|
||||||
match_arms.push(quote! {
|
match_arms.push(quote! {
|
||||||
@@ -501,7 +542,58 @@ pub fn derive_enum_serialize(input: TokenStream) -> TokenStream {
|
|||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
#[proc_macro_derive(EnumDeserialize, attributes(enumscribe))]
|
#[proc_macro_derive(EnumDeserialize, attributes(enumscribe))]
|
||||||
pub fn derive_enum_deserialize(input: TokenStream) -> TokenStream {
|
pub fn derive_enum_deserialize(input: TokenStream) -> TokenStream {
|
||||||
todo!()
|
let input: DeriveInput = syn::parse(input)
|
||||||
|
.expect("failed to parse input");
|
||||||
|
|
||||||
|
let enum_data = proc_try!(get_enum_data(&input));
|
||||||
|
let parsed_enum = proc_try!(enums::parse_enum(enum_data));
|
||||||
|
|
||||||
|
let enum_ident = &input.ident;
|
||||||
|
|
||||||
|
let deserializer_ident = quote! { __enumscribe_deserializer };
|
||||||
|
let deserialized_string_ident = quote! { __enumscribe_deserialized_string };
|
||||||
|
let deserialized_str_ident = quote! { __enumscribe_deserialized_str };
|
||||||
|
|
||||||
|
let variant_strings = parsed_enum.variants.iter()
|
||||||
|
.filter(|variant| match &variant.v_type {
|
||||||
|
VariantType::Ignore => false,
|
||||||
|
_ => true
|
||||||
|
})
|
||||||
|
.map(|variant| variant.data.ident.to_string())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let main_match = proc_try!(gen_unscribe_match(
|
||||||
|
enum_ident,
|
||||||
|
&parsed_enum,
|
||||||
|
&deserialized_str_ident,
|
||||||
|
|constructed_named_variant| quote! {
|
||||||
|
::std::result::Result::Ok(#constructed_named_variant)
|
||||||
|
},
|
||||||
|
|constructed_other_variant| quote! {
|
||||||
|
::std::result::Result::Ok(#constructed_other_variant)
|
||||||
|
},
|
||||||
|
|_| Ok(quote! {
|
||||||
|
__enumscribe_deserialize_base_case => ::std::result::Result::Err(
|
||||||
|
::serde::de::Error::unknown_variant(
|
||||||
|
__enumscribe_deserialize_base_case,
|
||||||
|
&[#(#variant_strings),*]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
|
||||||
|
(quote! {
|
||||||
|
impl<'de> ::serde::Deserialize<'de> for #enum_ident {
|
||||||
|
fn deserialize<D>(#deserializer_ident: D) -> ::std::result::Result<Self, D::Error>
|
||||||
|
where D: ::serde::Deserializer<'de>
|
||||||
|
{
|
||||||
|
let #deserialized_string_ident = <::std::string::String as ::serde::Deserialize<'_>>
|
||||||
|
::deserialize(#deserializer_ident)?;
|
||||||
|
let #deserialized_str_ident = #deserialized_string_ident.as_str();
|
||||||
|
#main_match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_enum_data(input: &DeriveInput) -> MacroResult<&DataEnum> {
|
fn get_enum_data(input: &DeriveInput) -> MacroResult<&DataEnum> {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use enumscribe::*;
|
use enumscribe::*;
|
||||||
|
|
||||||
#[derive(TryScribeCowStr, Unscribe, EnumSerialize, Eq, PartialEq, Debug)]
|
#[derive(TryScribeCowStr, Unscribe, EnumSerialize, EnumDeserialize, Eq, PartialEq, Debug)]
|
||||||
enum Airport {
|
enum Airport {
|
||||||
#[enumscribe(str = "LHR")]
|
#[enumscribe(str = "LHR")]
|
||||||
Heathrow,
|
Heathrow,
|
||||||
@@ -16,7 +16,7 @@ enum Airport {
|
|||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Eq, PartialEq, Debug)]
|
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
|
||||||
struct AirportInfo {
|
struct AirportInfo {
|
||||||
airport: Airport,
|
airport: Airport,
|
||||||
info: String,
|
info: String,
|
||||||
@@ -41,6 +41,10 @@ fn main() {
|
|||||||
airport: Airport::Gatwick(),
|
airport: Airport::Gatwick(),
|
||||||
info: "It's somewhere in London, innit".to_owned()
|
info: "It's somewhere in London, innit".to_owned()
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("{}", serde_json::to_string(&info).unwrap());
|
println!("{}", serde_json::to_string(&info).unwrap());
|
||||||
|
|
||||||
|
println!();
|
||||||
|
|
||||||
|
let info_str = r#"{ "airport": "lgw", "info": "Fun Gatwick fact: I'm fresh out of Gatwick facts" }"#;
|
||||||
|
println!("{:?}", serde_json::from_str::<AirportInfo>(info_str).unwrap());
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user