enum-ordinalize-3.1.13/.cargo_vcs_info.json0000644000000001120000000000100142150ustar { "git": { "sha1": "1d0db0167840242e857598c2e90c6f7bfd9792f4" } } enum-ordinalize-3.1.13/Cargo.toml0000644000000024230000000000100122220ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.56" name = "enum-ordinalize" version = "3.1.13" authors = ["Magic Len "] include = ["src/**/*", "Cargo.toml", "README.md", "LICENSE"] description = "This crates provides a procedural macro to let enums not only get its variants' ordinal but also be constructed from an ordinal." homepage = "https://magiclen.org/enum-ordinalize" keywords = ["enum", "ordinal", "ordinalize", "number"] categories = ["no-std", "data-structures"] license = "MIT" repository = "https://github.com/magiclen/enum-ordinalize" resolver = "2" [lib] proc-macro = true [dependencies.num-bigint] version = "0.4" [dependencies.num-traits] version = "0.2" [dependencies.proc-macro2] version = "1" [dependencies.quote] version = "1" [dependencies.syn] version = "2" [features] nightly-test = [] enum-ordinalize-3.1.13/Cargo.toml.orig000064400000000000000000000013130072674642500157300ustar 00000000000000[package] name = "enum-ordinalize" version = "3.1.13" authors = ["Magic Len "] edition = "2021" rust-version = "1.56" repository = "https://github.com/magiclen/enum-ordinalize" homepage = "https://magiclen.org/enum-ordinalize" keywords = ["enum", "ordinal", "ordinalize", "number"] categories = ["no-std", "data-structures"] description = "This crates provides a procedural macro to let enums not only get its variants' ordinal but also be constructed from an ordinal." license = "MIT" include = ["src/**/*", "Cargo.toml", "README.md", "LICENSE"] [lib] proc-macro = true [dependencies] proc-macro2 = "1" syn = "2" quote = "1" num-traits = "0.2" num-bigint = "0.4" [features] nightly-test = [] enum-ordinalize-3.1.13/LICENSE000064400000000000000000000020660072674642500140540ustar 00000000000000MIT License Copyright (c) 2018 magiclen.org (Ron Li) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. enum-ordinalize-3.1.13/README.md000064400000000000000000000104430072674642500143240ustar 00000000000000Enum Ordinalize ==================== [![CI](https://github.com/magiclen/enum-ordinalize/actions/workflows/ci.yml/badge.svg)](https://github.com/magiclen/enum-ordinalize/actions/workflows/ci.yml) This crates provides a procedural macro to let enums not only get its variants' ordinal but also be constructed from an ordinal. ## Ordinalize Use `#[derive(Ordinalize)]` to make an enum (which must only has unit variants) have `from_ordinal_unsafe`, `from_ordinal`, `variants`, and `variant_count` associated functions and a `ordinal` method. ```rust #[macro_use] extern crate enum_ordinalize; #[derive(Debug, PartialEq, Eq, Ordinalize)] enum MyEnum { Zero, One, Two, } assert_eq!(0i8, MyEnum::Zero.ordinal()); assert_eq!(1i8, MyEnum::One.ordinal()); assert_eq!(2i8, MyEnum::Two.ordinal()); assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0i8)); assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1i8)); assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2i8)); assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0i8) }); assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1i8) }); assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2i8) }); ``` ### Get Variants ```rust #[macro_use] extern crate enum_ordinalize; #[derive(Debug, PartialEq, Eq, Ordinalize)] enum MyEnum { Zero, One, Two, } assert_eq!([MyEnum::Zero, MyEnum::One, MyEnum::Two], MyEnum::variants()); assert_eq!(3, MyEnum::variant_count()); ``` `variants` and `variant_count` are constant functions. ## The (Ordinal) Size of an Enum The ordinal value is an integer whose size is determined by the enum itself. The larger (or the smaller if it's negative) the variants' values are, the bigger the enum size is. For example, ```rust #[macro_use] extern crate enum_ordinalize; #[derive(Debug, PartialEq, Eq, Ordinalize)] enum MyEnum { Zero, One, Two, Thousand = 1000, } assert_eq!(0i16, MyEnum::Zero.ordinal()); assert_eq!(1i16, MyEnum::One.ordinal()); assert_eq!(2i16, MyEnum::Two.ordinal()); assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0i16)); assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1i16)); assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2i16)); assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0i16) }); assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1i16) }); assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2i16) }); ``` In order to store `1000`, the size of `MyEnum` grows. Thus, the ordinal is in `i16` instead of `i8`. You can use the `#[repr(type)]` attribute to control the size explicitly. For instance, ```rust #[macro_use] extern crate enum_ordinalize; #[derive(Debug, PartialEq, Eq, Ordinalize)] #[repr(usize)] enum MyEnum { Zero, One, Two, Thousand = 1000, } assert_eq!(0usize, MyEnum::Zero.ordinal()); assert_eq!(1usize, MyEnum::One.ordinal()); assert_eq!(2usize, MyEnum::Two.ordinal()); assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0usize)); assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1usize)); assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2usize)); assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0usize) }); assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1usize) }); assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2usize) }); ``` ## Useful Increments The integers represented by variants are extended in successive increments and can be set explicitly from anywhere. ```rust #[macro_use] extern crate enum_ordinalize; #[derive(Debug, PartialEq, Eq, Ordinalize)] enum MyEnum { Two = 2, Three, Four, Eight = 8, Nine, NegativeTen = -10, NegativeNine, } assert_eq!(4i8, MyEnum::Four.ordinal()); assert_eq!(9i8, MyEnum::Nine.ordinal()); assert_eq!(-9i8, MyEnum::NegativeNine.ordinal()); assert_eq!(Some(MyEnum::Four), MyEnum::from_ordinal(4i8)); assert_eq!(Some(MyEnum::Nine), MyEnum::from_ordinal(9i8)); assert_eq!(Some(MyEnum::NegativeNine), MyEnum::from_ordinal(-9i8)); assert_eq!(MyEnum::Four, unsafe { MyEnum::from_ordinal_unsafe(4i8) }); assert_eq!(MyEnum::Nine, unsafe { MyEnum::from_ordinal_unsafe(9i8) }); assert_eq!(MyEnum::NegativeNine, unsafe { MyEnum::from_ordinal_unsafe(-9i8) }); ``` ## Crates.io https://crates.io/crates/enum-ordinalize ## Documentation https://docs.rs/enum-ordinalize ## License [MIT](LICENSE)enum-ordinalize-3.1.13/src/big_int_wrapper.rs000064400000000000000000000026300072674642500173540ustar 00000000000000use num_bigint::BigInt; use num_traits::{Signed, ToPrimitive}; use proc_macro2::{Literal, TokenStream}; use quote::{quote, ToTokens, TokenStreamExt}; use syn::Expr; pub(crate) enum BigIntWrapper<'a> { Integer(BigInt), Constant(&'a Expr, usize), } impl<'a> From for BigIntWrapper<'a> { #[inline] fn from(v: BigInt) -> BigIntWrapper<'a> { BigIntWrapper::Integer(v) } } impl<'a> From<(&'a Expr, usize)> for BigIntWrapper<'a> { #[inline] fn from((expr, counter): (&'a Expr, usize)) -> BigIntWrapper<'a> { BigIntWrapper::Constant(expr, counter) } } impl<'a> ToTokens for BigIntWrapper<'a> { #[inline] fn to_tokens(&self, tokens: &mut TokenStream) { match self { BigIntWrapper::Integer(v) => { let lit = if v.is_negative() { Literal::i128_unsuffixed(v.to_i128().unwrap()) } else { Literal::u128_unsuffixed(v.to_u128().unwrap()) }; tokens.append(lit); }, BigIntWrapper::Constant(expr, counter) => { let counter = *counter; if counter > 0 { tokens.extend(quote!(#expr +)); tokens.append(Literal::usize_unsuffixed(counter)); } else { tokens.extend(quote!(#expr)); } }, } } } enum-ordinalize-3.1.13/src/lib.rs000064400000000000000000000421330072674642500147510ustar 00000000000000/*! # Enum Ordinalize This crates provides a procedural macro to let enums not only get its variants' ordinal but also be constructed from an ordinal. ## Ordinalize Use `#[derive(Ordinalize)]` to make an enum (which must only has unit variants) have `from_ordinal_unsafe`, `from_ordinal`, `variants`, and `variant_count` associated functions and a `ordinal` method. ```rust #[macro_use] extern crate enum_ordinalize; #[derive(Debug, PartialEq, Eq, Ordinalize)] enum MyEnum { Zero, One, Two, } assert_eq!(0i8, MyEnum::Zero.ordinal()); assert_eq!(1i8, MyEnum::One.ordinal()); assert_eq!(2i8, MyEnum::Two.ordinal()); assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0i8)); assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1i8)); assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2i8)); assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0i8) }); assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1i8) }); assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2i8) }); ``` ### Get Variants ```rust #[macro_use] extern crate enum_ordinalize; #[derive(Debug, PartialEq, Eq, Ordinalize)] enum MyEnum { Zero, One, Two, } assert_eq!([MyEnum::Zero, MyEnum::One, MyEnum::Two], MyEnum::variants()); assert_eq!(3, MyEnum::variant_count()); ``` `variants` and `variant_count` are constant functions. ## The (Ordinal) Size of an Enum The ordinal value is an integer whose size is determined by the enum itself. The larger (or the smaller if it's negative) the variants' values are, the bigger the enum size is. For example, ```rust #[macro_use] extern crate enum_ordinalize; #[derive(Debug, PartialEq, Eq, Ordinalize)] enum MyEnum { Zero, One, Two, Thousand = 1000, } assert_eq!(0i16, MyEnum::Zero.ordinal()); assert_eq!(1i16, MyEnum::One.ordinal()); assert_eq!(2i16, MyEnum::Two.ordinal()); assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0i16)); assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1i16)); assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2i16)); assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0i16) }); assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1i16) }); assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2i16) }); ``` In order to store `1000`, the size of `MyEnum` grows. Thus, the ordinal is in `i16` instead of `i8`. You can use the `#[repr(type)]` attribute to control the size explicitly. For instance, ```rust #[macro_use] extern crate enum_ordinalize; #[derive(Debug, PartialEq, Eq, Ordinalize)] #[repr(usize)] enum MyEnum { Zero, One, Two, Thousand = 1000, } assert_eq!(0usize, MyEnum::Zero.ordinal()); assert_eq!(1usize, MyEnum::One.ordinal()); assert_eq!(2usize, MyEnum::Two.ordinal()); assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0usize)); assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1usize)); assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2usize)); assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0usize) }); assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1usize) }); assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2usize) }); ``` ## Useful Increment The integers represented by variants are extended in successive increments and can be set explicitly from anywhere. ```rust #[macro_use] extern crate enum_ordinalize; #[derive(Debug, PartialEq, Eq, Ordinalize)] enum MyEnum { Two = 2, Three, Four, Eight = 8, Nine, NegativeTen = -10, NegativeNine, } assert_eq!(4i8, MyEnum::Four.ordinal()); assert_eq!(9i8, MyEnum::Nine.ordinal()); assert_eq!(-9i8, MyEnum::NegativeNine.ordinal()); assert_eq!(Some(MyEnum::Four), MyEnum::from_ordinal(4i8)); assert_eq!(Some(MyEnum::Nine), MyEnum::from_ordinal(9i8)); assert_eq!(Some(MyEnum::NegativeNine), MyEnum::from_ordinal(-9i8)); assert_eq!(MyEnum::Four, unsafe { MyEnum::from_ordinal_unsafe(4i8) }); assert_eq!(MyEnum::Nine, unsafe { MyEnum::from_ordinal_unsafe(9i8) }); assert_eq!(MyEnum::NegativeNine, unsafe { MyEnum::from_ordinal_unsafe(-9i8) }); ``` */ #![no_std] extern crate alloc; mod big_int_wrapper; mod panic; mod variant_type; use alloc::{string::ToString, vec::Vec}; use core::str::FromStr; use big_int_wrapper::BigIntWrapper; use num_bigint::BigInt; use proc_macro::TokenStream; use quote::quote; use syn::{Data, DeriveInput, Expr, Fields, Ident, Lit, Meta, UnOp}; use variant_type::VariantType; fn derive_input_handler(ast: DeriveInput) -> TokenStream { let mut variant_type = VariantType::default(); for attr in ast.attrs { if attr.path().is_ident("repr") { // #[repr(u8)], #[repr(u16)], ..., etc. if let Meta::List(list) = attr.meta { let typ_name = list.tokens.to_string(); variant_type = VariantType::from_str(typ_name); } } } let name = &ast.ident; match ast.data { Data::Enum(data) => { if data.variants.is_empty() { panic::no_variant(); } let mut values: Vec = Vec::with_capacity(data.variants.len()); let mut variant_idents: Vec<&Ident> = Vec::with_capacity(data.variants.len()); let mut use_constant_counter = false; if VariantType::Nondetermined == variant_type { let mut min = BigInt::from(u128::MAX); let mut max = BigInt::from(i128::MIN); let mut counter = BigInt::default(); for variant in data.variants.iter() { if let Fields::Unit = variant.fields { let value = if let Some((_, exp)) = variant.discriminant.as_ref() { match exp { Expr::Lit(lit) => { let lit = &lit.lit; let value = match lit { Lit::Int(value) => { let value = value.base10_digits(); BigInt::from_str(value).unwrap() }, _ => panic::unsupported_discriminant(), }; counter = value.clone(); value }, Expr::Unary(unary) => match unary.op { UnOp::Neg(_) => match unary.expr.as_ref() { Expr::Lit(lit) => { let lit = &lit.lit; let value = match lit { Lit::Int(value) => { let value = value.base10_digits(); -BigInt::from_str(value).unwrap() }, _ => panic::unsupported_discriminant(), }; counter = value.clone(); value }, Expr::Path(_) | Expr::Cast(_) | Expr::Binary(_) | Expr::Call(_) => { panic::constant_variable_on_non_determined_size_enum() }, _ => panic::unsupported_discriminant(), }, _ => panic::unsupported_discriminant(), }, Expr::Path(_) | Expr::Cast(_) | Expr::Binary(_) | Expr::Call(_) => { panic::constant_variable_on_non_determined_size_enum() }, _ => panic::unsupported_discriminant(), } } else { counter.clone() }; if min > value { min = value.clone(); } if max < value { max = value.clone(); } variant_idents.push(&variant.ident); counter += 1; values.push(BigIntWrapper::from(value)); } else { panic::not_unit_variant(); } } if min >= BigInt::from(i8::MIN) && max <= BigInt::from(i8::MAX) { variant_type = VariantType::I8; } else if min >= BigInt::from(i16::MIN) && max <= BigInt::from(i16::MAX) { variant_type = VariantType::I16; } else if min >= BigInt::from(i32::MIN) && max <= BigInt::from(i32::MAX) { variant_type = VariantType::I32; } else if min >= BigInt::from(i64::MIN) && max <= BigInt::from(i64::MAX) { variant_type = VariantType::I64; } else if min >= BigInt::from(i128::MIN) && max <= BigInt::from(i128::MAX) { variant_type = VariantType::I128; } else { panic::unsupported_discriminant() } } else { let mut counter = BigInt::default(); let mut constant_counter = 0; let mut last_exp: Option<&Expr> = None; for variant in data.variants.iter() { if let Fields::Unit = variant.fields { if let Some((_, exp)) = variant.discriminant.as_ref() { match exp { Expr::Lit(lit) => { let lit = &lit.lit; let value = match lit { Lit::Int(value) => { let value = value.base10_digits(); BigInt::from_str(value).unwrap() }, _ => panic::unsupported_discriminant(), }; values.push(BigIntWrapper::from(value.clone())); counter = value + 1; last_exp = None; }, Expr::Unary(unary) => match unary.op { UnOp::Neg(_) => match unary.expr.as_ref() { Expr::Lit(lit) => { let lit = &lit.lit; let value = match lit { Lit::Int(value) => { let value = value.base10_digits(); -BigInt::from_str(value).unwrap() }, _ => panic::unsupported_discriminant(), }; values.push(BigIntWrapper::from(value.clone())); counter = value + 1; last_exp = None; }, Expr::Path(_) => { values.push(BigIntWrapper::from((exp, 0))); last_exp = Some(exp); constant_counter = 1; }, Expr::Cast(_) | Expr::Binary(_) | Expr::Call(_) => { values.push(BigIntWrapper::from((exp, 0))); last_exp = Some(exp); constant_counter = 1; use_constant_counter = true; }, _ => panic::unsupported_discriminant(), }, _ => panic::unsupported_discriminant(), }, Expr::Path(_) => { values.push(BigIntWrapper::from((exp, 0))); last_exp = Some(exp); constant_counter = 1; }, Expr::Cast(_) | Expr::Binary(_) | Expr::Call(_) => { values.push(BigIntWrapper::from((exp, 0))); last_exp = Some(exp); constant_counter = 1; use_constant_counter = true; }, _ => panic::unsupported_discriminant(), } } else if let Some(exp) = last_exp.as_ref() { values.push(BigIntWrapper::from((*exp, constant_counter))); constant_counter += 1; use_constant_counter = true; } else { values.push(BigIntWrapper::from(counter.clone())); counter += 1; } variant_idents.push(&variant.ident); } else { panic::not_unit_variant(); } } } let ordinal = quote! { #[inline] pub fn ordinal(&self) -> #variant_type { match self { #( Self::#variant_idents => #values, )* } } }; let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); let from_ordinal_unsafe = if data.variants.len() == 1 { let variant_idents = &data.variants[0].ident; quote! { #[inline] pub unsafe fn from_ordinal_unsafe(_number: #variant_type) -> #name #ty_generics { Self::#variant_idents } } } else { quote! { #[inline] pub unsafe fn from_ordinal_unsafe(number: #variant_type) -> #name #ty_generics { ::core::mem::transmute(number) } } }; let from_ordinal = if use_constant_counter { quote! { #[inline] pub fn from_ordinal(number: #variant_type) -> Option<#name #ty_generics> { if false { unreachable!() } #( else if number == #values { Some(Self::#variant_idents) } )* else { None } } } } else { quote! { #[inline] pub fn from_ordinal(number: #variant_type) -> Option<#name #ty_generics> { match number{ #( #values => Some(Self::#variant_idents), )* _ => None } } } }; let variant_count = variant_idents.len(); let variants = quote! { #[inline] pub const fn variants() -> [#name #ty_generics; #variant_count] { [#( Self::#variant_idents, )*] } }; let variant_count = quote! { #[inline] pub const fn variant_count() -> usize { #variant_count } }; let ordinalize_impl = quote! { impl #impl_generics #name #ty_generics #where_clause { #from_ordinal_unsafe #from_ordinal #ordinal #variants #variant_count } }; ordinalize_impl.into() }, _ => { panic::not_enum(); }, } } #[proc_macro_derive(Ordinalize)] pub fn ordinalize_derive(input: TokenStream) -> TokenStream { derive_input_handler(syn::parse(input).unwrap()) } enum-ordinalize-3.1.13/src/panic.rs000064400000000000000000000014740072674642500153000ustar 00000000000000#[inline] pub fn not_enum() -> ! { panic!("Only enums can be ordinalized.") } #[inline] pub fn not_unit_variant() -> ! { panic!("An ordinalized enum can only have unit variants.") } #[inline] pub fn no_variant() -> ! { panic!("An ordinalized enum needs to have at least one variant.") } #[inline] pub fn unsupported_discriminant() -> ! { panic!( "The discriminant of a variant of an ordinalized enum needs to be a legal literal \ integer, a constant variable/function or a constant expression." ) } #[inline] pub fn constant_variable_on_non_determined_size_enum() -> ! { panic!( "The discriminant of a variant can be assigned not to a literal integer only when the \ ordinalized enum is using the `repr` attribute to determine it's size before compilation." ) } enum-ordinalize-3.1.13/src/variant_type.rs000064400000000000000000000035770072674642500167210ustar 00000000000000use proc_macro2::{Ident, Span, TokenStream}; use quote::{ToTokens, TokenStreamExt}; #[allow(clippy::upper_case_acronyms)] #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub(crate) enum VariantType { ISIZE, I8, I16, I32, I64, I128, USIZE, U8, U16, U32, U64, U128, Nondetermined, } impl VariantType { #[inline] pub(crate) fn from_str>(s: S) -> VariantType { let s = s.as_ref(); match s { "isize" => VariantType::ISIZE, "i8" => VariantType::I8, "i16" => VariantType::I16, "i32" => VariantType::I32, "i64" => VariantType::I64, "i128" => VariantType::I128, "usize" => VariantType::USIZE, "u8" => VariantType::U8, "u16" => VariantType::U16, "u32" => VariantType::U32, "u64" => VariantType::U64, "u128" => VariantType::U128, _ => VariantType::Nondetermined, } } #[inline] pub(crate) fn as_str(&self) -> &'static str { match self { VariantType::ISIZE => "isize", VariantType::I8 => "i8", VariantType::I16 => "i16", VariantType::I32 => "i32", VariantType::I64 => "i64", VariantType::I128 => "i128", VariantType::USIZE => "usize", VariantType::U8 => "u8", VariantType::U16 => "u16", VariantType::U32 => "u32", VariantType::U64 => "u64", VariantType::U128 => "u128", _ => unreachable!(), } } } impl Default for VariantType { #[inline] fn default() -> Self { VariantType::Nondetermined } } impl ToTokens for VariantType { #[inline] fn to_tokens(&self, tokens: &mut TokenStream) { tokens.append(Ident::new(self.as_str(), Span::call_site())); } }