[英]How to convert the name of a enum's variant to a String in RUST?
I am wondering how to implement a method for any enum that will return the variant identifier as a String or &'static str, without using any external crate.我想知道如何为任何枚举实现一个方法,该方法将变量标识符作为字符串或 &'static str 返回,而不使用任何外部板条箱。 Something like:就像是:
pub enum MyEnum {
EnumVariant1
EnumVariant2
}
impl MyEnum {
fn to_string(&self) -> String {
// do Rust stuff here
}
}
As stated in my comment I believe a custom derive macro may be the easiest option (although I could be missing something) so here is a basic implementation of one:正如我的评论中所述,我相信自定义派生宏可能是最简单的选择(尽管我可能会遗漏某些内容),因此这里是一个基本实现:
// lib.rs in enum_name
extern crate self as enum_name;
pub use enum_name_derive::EnumName;
pub trait EnumName {
fn enum_name(&self) -> &'static str;
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(EnumName)]
#[allow(dead_code)]
enum MyEnum<'a, T> {
VariantA,
VariantB(T, i32),
AnotherOne { x: &'a str },
}
#[test]
fn test_enum_name() {
assert_eq!("VariantA", MyEnum::VariantA::<u32>.enum_name());
assert_eq!("VariantB", MyEnum::VariantB(1, 2).enum_name());
assert_eq!(
"AnotherOne",
MyEnum::AnotherOne::<u8> { x: "test" }.enum_name()
);
}
}
// lib.rs in enum_name_derive
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Fields};
#[proc_macro_derive(EnumName)]
pub fn derive_proto_read(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let ident = input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let variants = match input.data {
Data::Enum(data) => data.variants.into_iter().map(|variant| {
let ident = variant.ident;
let ident_string = ident.to_string();
let fields = match variant.fields {
Fields::Named(_) => quote!({ .. }),
Fields::Unnamed(_) => quote!((..)),
Fields::Unit => quote!(),
};
quote! {
Self::#ident#fields => #ident_string
}
}),
_ => panic!("not an enum"),
};
(quote! {
impl #impl_generics enum_name::EnumName for #ident #ty_generics #where_clause {
fn enum_name(&self) -> &'static str {
match self {
#(#variants),*
}
}
}
})
.into()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.