mirror of
https://github.com/danog/strum.git
synced 2025-01-22 05:52:10 +01:00
implement From<Enum> for &'static str in case of AsStaticRef derive (#40)
* implement From<Enum> for &'static str in case of AsStaticRef derive * make possible to use <&'static str>::from(Enum) without strum crate * mark AsStaticRef trait as deprecated
This commit is contained in:
parent
cb3a611b0e
commit
fe6c20a249
@ -372,7 +372,7 @@
|
||||
//! assert_eq!(MyVariants::Variant0, MyEnum::Variant0(true).into());
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! 8. `EnumCount`: for a given enum generates implementation of `strum::EnumCount`,
|
||||
//! which returns number of variants via `strum::EnumCount::count` method,
|
||||
//! also for given `enum MyEnum` generates `const MYENUM_COUNT: usize`
|
||||
@ -692,6 +692,7 @@ pub trait EnumProperty {
|
||||
|
||||
/// A cheap reference-to-reference conversion. Used to convert a value to a
|
||||
/// reference value with `'static` lifetime within generic code.
|
||||
/// #[deprecated(since="0.13.0", note="please use `#[derive(IntoStaticStr)]` instead")]
|
||||
pub trait AsStaticRef<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
@ -699,8 +700,8 @@ where
|
||||
fn as_static(&self) -> &'static T;
|
||||
}
|
||||
|
||||
/// A trait for capturing the number of variants in Enum. This trait can be autoderived by
|
||||
/// `strum_macros`.
|
||||
/// A trait for capturing the number of variants in Enum. This trait can be autoderived by
|
||||
/// `strum_macros`.
|
||||
pub trait EnumCount {
|
||||
fn count() -> usize;
|
||||
}
|
||||
|
@ -70,17 +70,57 @@ pub fn as_ref_str_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_static_str_inner(ast: &syn::DeriveInput) -> TokenStream {
|
||||
pub enum GenerateTraitVariant {
|
||||
AsStaticStr,
|
||||
From,
|
||||
}
|
||||
|
||||
pub fn as_static_str_inner(
|
||||
ast: &syn::DeriveInput,
|
||||
trait_variant: GenerateTraitVariant,
|
||||
) -> TokenStream {
|
||||
let name = &ast.ident;
|
||||
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
|
||||
let arms = get_arms(ast);
|
||||
quote!{
|
||||
impl #impl_generics ::strum::AsStaticRef<str> for #name #ty_generics #where_clause {
|
||||
fn as_static(&self) -> &'static str {
|
||||
match *self {
|
||||
#(#arms),*
|
||||
|
||||
let mut generics = ast.generics.clone();
|
||||
generics
|
||||
.params
|
||||
.push(syn::GenericParam::Lifetime(syn::LifetimeDef::new(
|
||||
parse_quote!('_derivative_strum),
|
||||
)));
|
||||
let (impl_generics2, _, _) = generics.split_for_impl();
|
||||
let arms2 = arms.clone();
|
||||
let arms3 = arms.clone();
|
||||
match trait_variant {
|
||||
GenerateTraitVariant::AsStaticStr => {
|
||||
quote!{
|
||||
impl #impl_generics ::strum::AsStaticRef<str> for #name #ty_generics #where_clause {
|
||||
fn as_static(&self) -> &'static str {
|
||||
match *self {
|
||||
#(#arms),*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GenerateTraitVariant::From => {
|
||||
quote! {
|
||||
impl #impl_generics ::std::convert::From<#name #ty_generics> for &'static str #where_clause {
|
||||
fn from(x: #name #ty_generics) -> &'static str {
|
||||
match x {
|
||||
#(#arms2),*
|
||||
}
|
||||
}
|
||||
}
|
||||
impl #impl_generics2 ::std::convert::From<&'_derivative_strum #name #ty_generics> for &'static str #where_clause {
|
||||
fn from(x: &'_derivative_strum #name #ty_generics) -> &'static str {
|
||||
match *x {
|
||||
#(#arms3),*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,16 @@ pub fn as_ref_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
pub fn as_static_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let ast = syn::parse(input).unwrap();
|
||||
|
||||
let toks = as_ref_str::as_static_str_inner(&ast);
|
||||
let toks = as_ref_str::as_static_str_inner(&ast, as_ref_str::GenerateTraitVariant::AsStaticStr);
|
||||
debug_print_generated(&ast, &toks);
|
||||
toks.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(IntoStaticStr, attributes(strum))]
|
||||
pub fn into_static_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let ast = syn::parse(input).unwrap();
|
||||
|
||||
let toks = as_ref_str::as_static_str_inner(&ast, as_ref_str::GenerateTraitVariant::From);
|
||||
debug_print_generated(&ast, &toks);
|
||||
toks.into()
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ extern crate strum_macros;
|
||||
use std::str::FromStr;
|
||||
use strum::AsStaticRef;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, EnumString, AsRefStr, AsStaticStr)]
|
||||
#[derive(Debug, Eq, PartialEq, EnumString, AsRefStr, AsStaticStr, IntoStaticStr)]
|
||||
enum Color {
|
||||
#[strum(to_string = "RedRed")]
|
||||
Red,
|
||||
@ -40,3 +40,48 @@ fn as_green_str() {
|
||||
assert_eq!("Green", (Color::Green(String::default())).as_ref());
|
||||
let _: &'static str = (Color::Green(String::default())).as_static();
|
||||
}
|
||||
|
||||
#[derive(IntoStaticStr)]
|
||||
enum Foo<'a> {
|
||||
A,
|
||||
C(&'a i32),
|
||||
}
|
||||
|
||||
#[derive(IntoStaticStr)]
|
||||
enum Boo<'a, T> {
|
||||
A(T),
|
||||
B,
|
||||
C(&'a i32),
|
||||
}
|
||||
|
||||
#[derive(IntoStaticStr)]
|
||||
enum Moo<'a, T>
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
A(T),
|
||||
B,
|
||||
C(&'a i32),
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_static_str() {
|
||||
assert_eq!("RedRed", <&'static str>::from(Color::Red));
|
||||
assert_eq!("blue", <&'static str>::from(Color::Blue { hue: 0 }));
|
||||
assert_eq!("yellow", <&'static str>::from(Color::Yellow));
|
||||
|
||||
assert_eq!("RedRed", <&'static str>::from(&Color::Red));
|
||||
assert_eq!("blue", <&'static str>::from(&Color::Blue { hue: 0 }));
|
||||
assert_eq!("yellow", <&'static str>::from(&Color::Yellow));
|
||||
|
||||
assert_eq!("A", <&'static str>::from(Foo::A));
|
||||
assert_eq!("C", <&'static str>::from(Foo::C(&17)));
|
||||
|
||||
assert_eq!("A", <&'static str>::from(Boo::A(17)));
|
||||
assert_eq!("B", <&'static str>::from(Boo::B::<i32>));
|
||||
assert_eq!("C", <&'static str>::from(Boo::C::<i32>(&17)));
|
||||
|
||||
assert_eq!("A", <&'static str>::from(Moo::A::<String>("aaa".into())));
|
||||
assert_eq!("B", <&'static str>::from(Moo::B::<String>));
|
||||
assert_eq!("C", <&'static str>::from(Moo::C::<String>(&17)));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user