Derive for Unscribe
This commit is contained in:
1 parent
1fab354030
commit
8f7f76d8ba
3 files changed
+160
-68
No files matched your search
@@ -31,7 +31,7 @@ pub(crate) enum VariantType<'a> {
|
|||||||
case_insensitive: bool,
|
case_insensitive: bool,
|
||||||
},
|
},
|
||||||
Other {
|
Other {
|
||||||
field_name: Option<&'a Ident> //use {} for constructor if Some, use () if None
|
field_name: Option<&'a Ident>
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,11 +59,8 @@ impl<'a> Variant<'a> {
|
|||||||
VariantType::Ignore => Ok(None),
|
VariantType::Ignore => Ok(None),
|
||||||
|
|
||||||
VariantType::Named { name, constructor, .. } => {
|
VariantType::Named { name, constructor, .. } => {
|
||||||
let pattern = match constructor {
|
let constructor_tokens = constructor.empty();
|
||||||
VariantConstructor::None => quote! { #enum_ident::#variant_ident },
|
let pattern = quote! { #enum_ident::#variant_ident #constructor_tokens };
|
||||||
VariantConstructor::Paren => quote! { #enum_ident::#variant_ident() },
|
|
||||||
VariantConstructor::Brace => quote! { #enum_ident::#variant_ident{} }
|
|
||||||
};
|
|
||||||
Ok(Some((pattern, named_fn(self, enum_ident, name)?)))
|
Ok(Some((pattern, named_fn(self, enum_ident, name)?)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +79,16 @@ impl<'a> Variant<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl VariantConstructor {
|
||||||
|
pub(crate) fn empty(&self) -> TokenStream2 {
|
||||||
|
match self {
|
||||||
|
VariantConstructor::None => quote! {},
|
||||||
|
VariantConstructor::Paren => quote! { () },
|
||||||
|
VariantConstructor::Brace => quote! { {} }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_enum(data: &DataEnum) -> MacroResult<Enum> {
|
pub(crate) fn parse_enum(data: &DataEnum) -> MacroResult<Enum> {
|
||||||
let mut variants = Vec::with_capacity(data.variants.len());
|
let mut variants = Vec::with_capacity(data.variants.len());
|
||||||
let mut taken_names = HashSet::new();
|
let mut taken_names = HashSet::new();
|
||||||
@@ -182,10 +189,10 @@ pub(crate) fn parse_enum(data: &DataEnum) -> MacroResult<Enum> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if case_insensitive {
|
if case_insensitive {
|
||||||
taken_insensitive_names.insert(lowercase_name);
|
&mut taken_insensitive_names
|
||||||
} else {
|
} else {
|
||||||
taken_sensitive_names.insert(lowercase_name);
|
&mut taken_sensitive_names
|
||||||
}
|
}.insert(lowercase_name);
|
||||||
|
|
||||||
// Return an error if the variant has any fields
|
// Return an error if the variant has any fields
|
||||||
if variant.fields.len() != 0 {
|
if variant.fields.len() != 0 {
|
||||||
|
|||||||
+135
-54
@@ -4,13 +4,13 @@
|
|||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
|
use proc_macro2::Ident;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{Data, DataEnum, DeriveInput};
|
use syn::{Data, DataEnum, DeriveInput};
|
||||||
|
|
||||||
use error::{MacroError, MacroResult};
|
use error::{MacroError, MacroResult};
|
||||||
|
|
||||||
use crate::enums::{Variant, VariantType};
|
use crate::enums::{Variant, VariantType, VariantConstructor};
|
||||||
use proc_macro2::Ident;
|
|
||||||
|
|
||||||
mod enums;
|
mod enums;
|
||||||
mod attribute;
|
mod attribute;
|
||||||
@@ -40,7 +40,7 @@ fn derive_scribe<F, G, E>(
|
|||||||
trait_return_type: TokenStream2,
|
trait_return_type: TokenStream2,
|
||||||
named_fn: F,
|
named_fn: F,
|
||||||
other_fn: G,
|
other_fn: G,
|
||||||
ignore_err_fn: E
|
ignore_err_fn: E,
|
||||||
) -> TokenStream
|
) -> TokenStream
|
||||||
where
|
where
|
||||||
F: Fn(&Variant, &Ident, &str) -> MacroResult<TokenStream2>,
|
F: Fn(&Variant, &Ident, &str) -> MacroResult<TokenStream2>,
|
||||||
@@ -82,7 +82,7 @@ fn derive_try_scribe<F, G>(
|
|||||||
trait_return_type: TokenStream2,
|
trait_return_type: TokenStream2,
|
||||||
named_fn: F,
|
named_fn: F,
|
||||||
other_fn: G,
|
other_fn: G,
|
||||||
ignore_result: TokenStream2
|
ignore_result: TokenStream2,
|
||||||
) -> TokenStream
|
) -> TokenStream
|
||||||
where
|
where
|
||||||
F: Fn(&Variant, &Ident, &str) -> MacroResult<TokenStream2>,
|
F: Fn(&Variant, &Ident, &str) -> MacroResult<TokenStream2>,
|
||||||
@@ -129,19 +129,15 @@ fn derive_try_scribe<F, G>(
|
|||||||
pub fn derive_scribe_static_str(input: TokenStream) -> TokenStream {
|
pub fn derive_scribe_static_str(input: TokenStream) -> TokenStream {
|
||||||
derive_scribe(
|
derive_scribe(
|
||||||
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.to_string(), variant.data.ident.to_string(), 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 \
|
||||||
@@ -149,7 +145,7 @@ pub fn derive_scribe_static_str(input: TokenStream) -> TokenStream {
|
|||||||
hint: try deriving TryScribeStaticStr instead",
|
hint: try deriving TryScribeStaticStr instead",
|
||||||
enum_ident.to_string(), variant.data.ident.to_string(), IGNORE,
|
enum_ident.to_string(), variant.data.ident.to_string(), IGNORE,
|
||||||
variant.data.ident.to_string(),
|
variant.data.ident.to_string(),
|
||||||
), variant.span)
|
), variant.span),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,22 +153,18 @@ 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 {
|
||||||
derive_try_scribe(
|
derive_try_scribe(
|
||||||
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.to_string(), variant.data.ident.to_string(), OTHER
|
||||||
), variant.span)),
|
), variant.span)),
|
||||||
|
quote! { ::std::option::Option::None },
|
||||||
quote! { ::std::option::Option::None }
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,18 +172,14 @@ 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 {
|
||||||
derive_scribe(
|
derive_scribe(
|
||||||
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 \
|
||||||
@@ -199,7 +187,7 @@ pub fn derive_scribe_string(input: TokenStream) -> TokenStream {
|
|||||||
hint: try deriving TryScribeString instead",
|
hint: try deriving TryScribeString instead",
|
||||||
enum_ident.to_string(), variant.data.ident.to_string(), IGNORE,
|
enum_ident.to_string(), variant.data.ident.to_string(), IGNORE,
|
||||||
variant.data.ident.to_string(),
|
variant.data.ident.to_string(),
|
||||||
), variant.span)
|
), variant.span),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,23 +195,19 @@ 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 {
|
||||||
derive_try_scribe(
|
derive_try_scribe(
|
||||||
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 }
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,20 +215,16 @@ 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 {
|
||||||
derive_scribe(
|
derive_scribe(
|
||||||
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 \
|
||||||
@@ -252,7 +232,7 @@ pub fn derive_scribe_cow_str(input: TokenStream) -> TokenStream {
|
|||||||
hint: try deriving TryScribeCowStr instead",
|
hint: try deriving TryScribeCowStr instead",
|
||||||
enum_ident.to_string(), variant.data.ident.to_string(), IGNORE,
|
enum_ident.to_string(), variant.data.ident.to_string(), IGNORE,
|
||||||
variant.data.ident.to_string(),
|
variant.data.ident.to_string(),
|
||||||
), variant.span)
|
), variant.span),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,16 +240,13 @@ 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 {
|
||||||
derive_try_scribe(
|
derive_try_scribe(
|
||||||
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(
|
||||||
@@ -277,38 +254,142 @@ pub fn derive_try_scribe_cow_str(input: TokenStream) -> TokenStream {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
quote! { ::std::option::Option::None },
|
||||||
quote! { ::std::option::Option::None }
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(Unscribe, attributes(enumscribe))]
|
#[proc_macro_derive(Unscribe, attributes(enumscribe))]
|
||||||
pub fn derive_unscribe(input: TokenStream) -> TokenStream {
|
pub fn derive_unscribe(input: TokenStream) -> TokenStream {
|
||||||
// let input: DeriveInput = syn::parse(input)
|
let input: DeriveInput = syn::parse(input)
|
||||||
// .expect("failed to 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 mut other_arm = None;
|
|
||||||
// let mut case_sensitive_arms = Vec::new();
|
|
||||||
// let mut case_insensitive_arms = Vec::new();
|
|
||||||
//
|
|
||||||
// for variant in parsed_enum.variants.iter() {
|
|
||||||
// match variant.v_type {
|
|
||||||
// VariantType::Ignore => {}
|
|
||||||
// VariantType::Named { .. } => {}
|
|
||||||
// VariantType::Other { .. } => {}
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
todo!()
|
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 mut all_ignored = true;
|
||||||
|
let mut other_arm = None;
|
||||||
|
let mut case_sensitive_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() {
|
||||||
|
let variant_ident = &variant.data.ident;
|
||||||
|
|
||||||
|
match &variant.v_type {
|
||||||
|
VariantType::Ignore => (),
|
||||||
|
|
||||||
|
VariantType::Named { name, constructor, case_insensitive } => {
|
||||||
|
all_ignored = false;
|
||||||
|
|
||||||
|
let match_pattern = if *case_insensitive {
|
||||||
|
let lowercase_name = name.to_lowercase();
|
||||||
|
quote! { #lowercase_name }
|
||||||
|
} else {
|
||||||
|
quote! { #name }
|
||||||
|
};
|
||||||
|
|
||||||
|
let constructor_tokens = constructor.empty();
|
||||||
|
let match_result = quote! { #enum_ident::#variant_ident #constructor_tokens };
|
||||||
|
|
||||||
|
if *case_insensitive {
|
||||||
|
&mut case_insensitive_arms
|
||||||
|
} else {
|
||||||
|
&mut case_sensitive_arms
|
||||||
|
}.push(quote! { #match_pattern => #match_result });
|
||||||
|
}
|
||||||
|
|
||||||
|
VariantType::Other { field_name } => {
|
||||||
|
all_ignored = false;
|
||||||
|
|
||||||
|
let unscribe_value = quote! { <_ as ::std::convert::Into<_>>::into(#to_unscribe_ident) };
|
||||||
|
|
||||||
|
let match_result = match field_name {
|
||||||
|
None => quote! {
|
||||||
|
#enum_ident::#variant_ident(#unscribe_value)
|
||||||
|
},
|
||||||
|
Some(field_name) => quote! {
|
||||||
|
#enum_ident::#variant_ident { #field_name: #unscribe_value }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
other_arm = Some(quote! { _ => #match_result })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if all_ignored {
|
||||||
|
return MacroError::new(format!(
|
||||||
|
"cannot derive Unscribe for {} because all variants are marked as {}\n\
|
||||||
|
hint: introduce at least one variant that is not marked as {}",
|
||||||
|
enum_ident.to_string(), IGNORE, IGNORE
|
||||||
|
), enum_ident.span()).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
let other_arm = match other_arm {
|
||||||
|
Some(other_arm) => other_arm,
|
||||||
|
None => return MacroError::new(format!(
|
||||||
|
"cannot derive Unscribe for {} because no variant is marked as {}\n\
|
||||||
|
explanation: since there is no {} variant, it cannot be guaranteed that every string \
|
||||||
|
can be successfully converted to a variant of {}\n\
|
||||||
|
hint: either introduce an {} variant, or try deriving TryUnscribe instead",
|
||||||
|
enum_ident.to_string(), OTHER, OTHER, enum_ident.to_string(), OTHER
|
||||||
|
), enum_ident.span()).into()
|
||||||
|
};
|
||||||
|
|
||||||
|
let case_insensitive_match = if case_insensitive_arms.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(quote! {
|
||||||
|
let __enumscribe_unscribe_lowercase = #to_unscribe_ident.to_lowercase();
|
||||||
|
match __enumscribe_unscribe_lowercase.as_str() {
|
||||||
|
#(#case_insensitive_arms,)*
|
||||||
|
#other_arm,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let main_match = match (case_sensitive_arms.is_empty(), case_insensitive_match) {
|
||||||
|
(true, None) => quote! {
|
||||||
|
match #to_unscribe_ident {
|
||||||
|
#other_arm,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
(false, None) => quote! {
|
||||||
|
match #to_unscribe_ident {
|
||||||
|
#(#case_sensitive_arms,)*
|
||||||
|
#other_arm,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
(true, Some(case_insensitive_match)) => {
|
||||||
|
case_insensitive_match
|
||||||
|
},
|
||||||
|
|
||||||
|
(false, Some(case_insensitive_match)) => quote! {
|
||||||
|
match #to_unscribe_ident {
|
||||||
|
#(#case_sensitive_arms,)*
|
||||||
|
_ => { #case_insensitive_match },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(quote! {
|
||||||
|
impl ::enumscribe::Unscribe for #enum_ident {
|
||||||
|
fn unscribe(#to_unscribe_ident: &str) -> Self {
|
||||||
|
#main_match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(TryUnscribe, attributes(enumscribe))]
|
#[proc_macro_derive(TryUnscribe, attributes(enumscribe))]
|
||||||
pub fn derive_try_unscribe(input: TokenStream) -> TokenStream {
|
pub fn derive_try_unscribe(input: TokenStream) -> TokenStream {
|
||||||
|
//TODO: make sure at least one variant is non-ignore
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
use enumscribe::*;
|
use enumscribe::*;
|
||||||
|
|
||||||
#[derive(TryScribeCowStr)]
|
#[derive(TryScribeCowStr, Unscribe, Eq, PartialEq, Debug)]
|
||||||
enum Airport {
|
enum Airport {
|
||||||
#[enumscribe(str = "LHR", case_insensitive)]
|
#[enumscribe(str = "LHR")]
|
||||||
Heathrow,
|
Heathrow,
|
||||||
#[enumscribe(str = "LGW", case_insensitive)]
|
#[enumscribe(str = "LGW", case_insensitive)]
|
||||||
Gatwick,
|
Gatwick(),
|
||||||
#[enumscribe(str = "LTN", case_insensitive)]
|
#[enumscribe(str = "LTN", case_insensitive)]
|
||||||
Luton,
|
Luton {},
|
||||||
#[enumscribe(str = "BHX", case_insensitive, ignore)]
|
#[enumscribe(str = "BHX", case_insensitive, ignore)]
|
||||||
BirminghamInternational,
|
BirminghamInternational,
|
||||||
#[enumscribe(other)]
|
#[enumscribe(other)]
|
||||||
@@ -15,9 +15,13 @@ enum Airport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let luton = Airport::Luton;
|
let luton = Airport::Luton {};
|
||||||
println!("Hello, {:?}!", luton.try_scribe());
|
println!("Hello, {:?}!", luton.try_scribe());
|
||||||
|
|
||||||
let other = Airport::Other("Dedicated EasyJet-only airport".to_owned());
|
let other = Airport::Other("Dedicated EasyJet-only airport".to_owned());
|
||||||
println!("Hello, {:?}!", other.try_scribe());
|
println!("Hello, {:?}!", other.try_scribe());
|
||||||
|
|
||||||
|
println!("{:?}", Airport::unscribe("LHR"));
|
||||||
|
println!("{:?}", Airport::unscribe("lhr"));
|
||||||
|
println!("{:?}", Airport::unscribe("lgw"));
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user