|
|
|
|
@ -27,7 +27,7 @@ macro_rules! proc_try {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[proc_macro_derive(ScribeString, attributes(enumscribe))]
|
|
|
|
|
pub fn derive_enum_to_string(input: TokenStream) -> TokenStream {
|
|
|
|
|
pub fn derive_scribe_string(input: TokenStream) -> TokenStream {
|
|
|
|
|
let input: DeriveInput = syn::parse(input)
|
|
|
|
|
.expect("failed to parse input");
|
|
|
|
|
|
|
|
|
|
@ -42,8 +42,12 @@ pub fn derive_enum_to_string(input: TokenStream) -> TokenStream {
|
|
|
|
|
|
|
|
|
|
for variant in parsed_enum.variants.iter() {
|
|
|
|
|
match variant.match_variant(
|
|
|
|
|
|name| Ok(quote! { <_ as ::std::borrow::ToOwned>::to_owned(#name) }),
|
|
|
|
|
|field| Ok(quote! { <_ as ::std::convert::Into<::std::string::String>>::into(#field) }),
|
|
|
|
|
|name| Ok(quote! {
|
|
|
|
|
<_ as ::std::borrow::ToOwned>::to_owned(#name)
|
|
|
|
|
}),
|
|
|
|
|
|field| Ok(quote! {
|
|
|
|
|
<_ as ::std::convert::Into<::std::string::String>>::into(#field)
|
|
|
|
|
}),
|
|
|
|
|
) {
|
|
|
|
|
Ok(Some((pattern, result))) => {
|
|
|
|
|
match_patterns.push(pattern);
|
|
|
|
|
@ -75,7 +79,7 @@ pub fn derive_enum_to_string(input: TokenStream) -> TokenStream {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[proc_macro_derive(TryScribeString, attributes(enumscribe))]
|
|
|
|
|
pub fn derive_try_enum_to_string(input: TokenStream) -> TokenStream {
|
|
|
|
|
pub fn derive_try_scribe_string(input: TokenStream) -> TokenStream {
|
|
|
|
|
let input: DeriveInput = syn::parse(input)
|
|
|
|
|
.expect("failed to parse input");
|
|
|
|
|
|
|
|
|
|
@ -91,8 +95,16 @@ pub fn derive_try_enum_to_string(input: TokenStream) -> TokenStream {
|
|
|
|
|
|
|
|
|
|
for variant in parsed_enum.variants.iter() {
|
|
|
|
|
match variant.match_variant(
|
|
|
|
|
|name| Ok(quote! { ::std::option::Option::Some(<_ as ::std::borrow::ToOwned>::to_owned(#name)) }),
|
|
|
|
|
|field| Ok(quote! { ::std::option::Option::Some(<_ as ::std::convert::Into<::std::string::String>>::into(#field)) }),
|
|
|
|
|
|name| Ok(quote! {
|
|
|
|
|
::std::option::Option::Some(
|
|
|
|
|
<_ as ::std::borrow::ToOwned>::to_owned(#name)
|
|
|
|
|
)
|
|
|
|
|
}),
|
|
|
|
|
|field| Ok(quote! {
|
|
|
|
|
::std::option::Option::Some(
|
|
|
|
|
<_ as ::std::convert::Into<::std::string::String>>::into(#field)
|
|
|
|
|
)
|
|
|
|
|
}),
|
|
|
|
|
) {
|
|
|
|
|
Ok(Some((pattern, result))) => {
|
|
|
|
|
match_patterns.push(pattern);
|
|
|
|
|
@ -123,6 +135,119 @@ pub fn derive_try_enum_to_string(input: TokenStream) -> TokenStream {
|
|
|
|
|
}).into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[proc_macro_derive(ScribeCowStr, attributes(enumscribe))]
|
|
|
|
|
pub fn derive_scribe_cow_str(input: TokenStream) -> TokenStream {
|
|
|
|
|
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 enum_idents = iter::repeat(enum_ident);
|
|
|
|
|
|
|
|
|
|
let mut match_patterns = Vec::with_capacity(parsed_enum.variants.len());
|
|
|
|
|
let mut match_results = Vec::with_capacity(parsed_enum.variants.len());
|
|
|
|
|
|
|
|
|
|
for variant in parsed_enum.variants.iter() {
|
|
|
|
|
match variant.match_variant(
|
|
|
|
|
|name| Ok(quote! {
|
|
|
|
|
::std::borrow::Cow::Borrowed(#name)
|
|
|
|
|
}),
|
|
|
|
|
|field| Ok(quote! {
|
|
|
|
|
::std::borrow::Cow::Owned(
|
|
|
|
|
<_ as ::std::convert::Into<::std::string::String>>::into(#field)
|
|
|
|
|
)
|
|
|
|
|
}),
|
|
|
|
|
) {
|
|
|
|
|
Ok(Some((pattern, result))) => {
|
|
|
|
|
match_patterns.push(pattern);
|
|
|
|
|
match_results.push(result);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
Ok(None) => return MacroError::new(format!(
|
|
|
|
|
"cannot derive ScribeCowStr for {} because the variant {} is marked as {}\n\
|
|
|
|
|
explanation: since {} is ignored, it cannot be guaranteed that the enum can \
|
|
|
|
|
always be successfully converted to a String\n\
|
|
|
|
|
hint: try deriving TryScribeCowStr instead",
|
|
|
|
|
enum_ident.to_string(), variant.data.ident.to_string(), IGNORE,
|
|
|
|
|
variant.data.ident.to_string(),
|
|
|
|
|
), variant.span).into(),
|
|
|
|
|
|
|
|
|
|
Err(err) => return err.into()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(quote! {
|
|
|
|
|
impl ::enumscribe::ScribeCowStr for #enum_ident {
|
|
|
|
|
fn scribe(&self) -> ::std::borrow::Cow<'static, str> {
|
|
|
|
|
match self {
|
|
|
|
|
#(#enum_idents::#match_patterns => #match_results,)*
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}).into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[proc_macro_derive(TryScribeCowStr, attributes(enumscribe))]
|
|
|
|
|
pub fn derive_try_scribe_cow_str(input: TokenStream) -> TokenStream {
|
|
|
|
|
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 enum_idents = iter::repeat(enum_ident);
|
|
|
|
|
|
|
|
|
|
let mut ignore_variant = false;
|
|
|
|
|
let mut match_patterns = Vec::with_capacity(parsed_enum.variants.len());
|
|
|
|
|
let mut match_results = Vec::with_capacity(parsed_enum.variants.len());
|
|
|
|
|
|
|
|
|
|
for variant in parsed_enum.variants.iter() {
|
|
|
|
|
match variant.match_variant(
|
|
|
|
|
|name| Ok(quote! {
|
|
|
|
|
::std::option::Option::Some(
|
|
|
|
|
::std::borrow::Cow::Borrowed(#name)
|
|
|
|
|
)
|
|
|
|
|
}),
|
|
|
|
|
|field| Ok(quote! {
|
|
|
|
|
::std::option::Option::Some(
|
|
|
|
|
::std::borrow::Cow::Owned(
|
|
|
|
|
<_ as ::std::convert::Into<::std::string::String>>::into(#field)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
}),
|
|
|
|
|
) {
|
|
|
|
|
Ok(Some((pattern, result))) => {
|
|
|
|
|
match_patterns.push(pattern);
|
|
|
|
|
match_results.push(result);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
Ok(None) => ignore_variant = true,
|
|
|
|
|
|
|
|
|
|
Err(err) => return err.into()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let ignore_arm = if ignore_variant {
|
|
|
|
|
quote! { _ => ::std::option::Option::None, }
|
|
|
|
|
} else {
|
|
|
|
|
quote! {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
(quote! {
|
|
|
|
|
impl ::enumscribe::TryScribeCowStr for #enum_ident {
|
|
|
|
|
fn try_scribe(&self) -> ::std::option::Option<::std::borrow::Cow<'static, str>> {
|
|
|
|
|
match self {
|
|
|
|
|
#(#enum_idents::#match_patterns => #match_results,)*
|
|
|
|
|
#ignore_arm
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}).into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn get_enum_data(input: &DeriveInput) -> MacroResult<&DataEnum> {
|
|
|
|
|
let enum_data = match &input.data {
|
|
|
|
|
Data::Enum(enum_data) => enum_data,
|
|
|
|
|
|