mirror of
https://github.com/danog/strum.git
synced 2025-01-22 14:02:27 +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());
|
//! assert_eq!(MyVariants::Variant0, MyEnum::Variant0(true).into());
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! 8. `EnumCount`: for a given enum generates implementation of `strum::EnumCount`,
|
//! 8. `EnumCount`: for a given enum generates implementation of `strum::EnumCount`,
|
||||||
//! which returns number of variants via `strum::EnumCount::count` method,
|
//! which returns number of variants via `strum::EnumCount::count` method,
|
||||||
//! also for given `enum MyEnum` generates `const MYENUM_COUNT: usize`
|
//! 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
|
/// A cheap reference-to-reference conversion. Used to convert a value to a
|
||||||
/// reference value with `'static` lifetime within generic code.
|
/// reference value with `'static` lifetime within generic code.
|
||||||
|
/// #[deprecated(since="0.13.0", note="please use `#[derive(IntoStaticStr)]` instead")]
|
||||||
pub trait AsStaticRef<T>
|
pub trait AsStaticRef<T>
|
||||||
where
|
where
|
||||||
T: ?Sized,
|
T: ?Sized,
|
||||||
@ -699,8 +700,8 @@ where
|
|||||||
fn as_static(&self) -> &'static T;
|
fn as_static(&self) -> &'static T;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait for capturing the number of variants in Enum. This trait can be autoderived by
|
/// A trait for capturing the number of variants in Enum. This trait can be autoderived by
|
||||||
/// `strum_macros`.
|
/// `strum_macros`.
|
||||||
pub trait EnumCount {
|
pub trait EnumCount {
|
||||||
fn count() -> usize;
|
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 name = &ast.ident;
|
||||||
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
|
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
|
||||||
let arms = get_arms(ast);
|
let arms = get_arms(ast);
|
||||||
quote!{
|
|
||||||
impl #impl_generics ::strum::AsStaticRef<str> for #name #ty_generics #where_clause {
|
let mut generics = ast.generics.clone();
|
||||||
fn as_static(&self) -> &'static str {
|
generics
|
||||||
match *self {
|
.params
|
||||||
#(#arms),*
|
.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 {
|
pub fn as_static_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
let ast = syn::parse(input).unwrap();
|
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);
|
debug_print_generated(&ast, &toks);
|
||||||
toks.into()
|
toks.into()
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ extern crate strum_macros;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use strum::AsStaticRef;
|
use strum::AsStaticRef;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, EnumString, AsRefStr, AsStaticStr)]
|
#[derive(Debug, Eq, PartialEq, EnumString, AsRefStr, AsStaticStr, IntoStaticStr)]
|
||||||
enum Color {
|
enum Color {
|
||||||
#[strum(to_string = "RedRed")]
|
#[strum(to_string = "RedRed")]
|
||||||
Red,
|
Red,
|
||||||
@ -40,3 +40,48 @@ fn as_green_str() {
|
|||||||
assert_eq!("Green", (Color::Green(String::default())).as_ref());
|
assert_eq!("Green", (Color::Green(String::default())).as_ref());
|
||||||
let _: &'static str = (Color::Green(String::default())).as_static();
|
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