chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

View File

@@ -0,0 +1,167 @@
use core::{
cmp::Ordering,
fmt::{self, Display, Formatter},
num::ParseIntError,
ops::Neg,
str::FromStr,
};
#[derive(Debug, Copy, Eq, Clone)]
pub(crate) enum Int128 {
Signed(i128),
Unsigned(u128),
}
impl PartialEq for Int128 {
#[inline]
fn eq(&self, other: &Int128) -> bool {
match self {
Self::Signed(i) => match other {
Self::Signed(i2) => i.eq(i2),
Self::Unsigned(u2) => {
if i.is_negative() {
false
} else {
(*i as u128).eq(u2)
}
},
},
Self::Unsigned(u) => match other {
Self::Signed(i2) => {
if i2.is_negative() {
false
} else {
u.eq(&(*i2 as u128))
}
},
Self::Unsigned(u2) => u.eq(u2),
},
}
}
}
impl PartialOrd for Int128 {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Int128 {
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
match self {
Self::Signed(i) => match other {
Self::Signed(i2) => i.cmp(i2),
Self::Unsigned(u2) => {
if i.is_negative() {
Ordering::Less
} else {
(*i as u128).cmp(u2)
}
},
},
Self::Unsigned(u) => match other {
Self::Signed(i2) => {
if i2.is_negative() {
Ordering::Greater
} else {
u.cmp(&(*i2 as u128))
}
},
Self::Unsigned(u2) => u.cmp(u2),
},
}
}
}
impl Display for Int128 {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Signed(i) => Display::fmt(i, f),
Self::Unsigned(u) => Display::fmt(u, f),
}
}
}
impl Default for Int128 {
#[inline]
fn default() -> Self {
Self::ZERO
}
}
impl Int128 {
pub(crate) const ZERO: Self = Self::Unsigned(0);
}
macro_rules! impl_from_signed {
(@inner $t: ty) => {
impl From<$t> for Int128 {
#[inline]
fn from(value: $t) -> Self {
Int128::Signed(value as i128)
}
}
};
($($t: ty),+ $(,)*) => {
$(
impl_from_signed!(@inner $t);
)*
};
}
impl_from_signed!(i8, i16, i32, i64, i128, isize);
impl FromStr for Int128 {
type Err = ParseIntError;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.starts_with('-') {
Ok(Self::Signed(s.parse()?))
} else {
Ok(Self::Unsigned(s.parse()?))
}
}
}
impl Neg for Int128 {
type Output = Int128;
fn neg(self) -> Self::Output {
match self {
Self::Signed(i) => {
if i == i128::MIN {
Self::Unsigned(1 << 127)
} else {
Self::Signed(-i)
}
},
Self::Unsigned(u) => match u.cmp(&(1 << 127)) {
Ordering::Equal => Self::Signed(i128::MIN),
Ordering::Less => Self::Signed(-(u as i128)),
Ordering::Greater => panic!("-{} is experiencing an overflow", u),
},
}
}
}
impl Int128 {
#[inline]
pub(crate) fn inc(&mut self) {
match self {
Self::Signed(i) => {
if *i == i128::MAX {
*self = Self::Unsigned(1 << 127)
} else {
*i += 1;
}
},
Self::Unsigned(u) => {
*u = u.saturating_add(1);
},
}
}
}

View File

@@ -0,0 +1,57 @@
use proc_macro2::{Literal, TokenStream};
use quote::{quote, ToTokens, TokenStreamExt};
use syn::Expr;
use crate::int128::Int128;
pub(crate) enum IntWrapper {
Integer(Int128),
Constant(Expr, usize),
}
impl From<Int128> for IntWrapper {
#[inline]
fn from(v: Int128) -> IntWrapper {
Self::Integer(v)
}
}
impl From<i128> for IntWrapper {
#[inline]
fn from(v: i128) -> IntWrapper {
Self::Integer(Int128::from(v))
}
}
impl From<(&Expr, usize)> for IntWrapper {
#[inline]
fn from((expr, counter): (&Expr, usize)) -> IntWrapper {
Self::Constant(expr.clone(), counter)
}
}
impl ToTokens for IntWrapper {
#[inline]
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
Self::Integer(v) => {
let lit = match v {
Int128::Signed(i) => Literal::i128_unsuffixed(*i),
Int128::Unsigned(u) => Literal::u128_unsuffixed(*u),
};
tokens.append(lit);
},
Self::Constant(expr, counter) => {
let counter = *counter;
if counter > 0 {
tokens.extend(quote!(#expr +));
tokens.append(Literal::usize_unsuffixed(counter));
} else {
tokens.extend(quote!(#expr));
}
},
}
}
}

808
vendor/enum-ordinalize-derive/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,808 @@
/*!
# Enum Ordinalize Derive
This library enables enums to not only obtain the ordinal values of their variants but also allows for the construction of enums from an ordinal value. See the [`enum-ordinalize`](https://crates.io/crates/enum-ordinalize) crate.
*/
#![no_std]
#[macro_use]
extern crate alloc;
mod int128;
mod int_wrapper;
mod panic;
mod variant_type;
use alloc::{string::ToString, vec::Vec};
use proc_macro::TokenStream;
use quote::quote;
use syn::{
parse::{Parse, ParseStream},
parse_macro_input,
punctuated::Punctuated,
spanned::Spanned,
Data, DeriveInput, Expr, Fields, Ident, Lit, Meta, Token, UnOp, Visibility,
};
use variant_type::VariantType;
use crate::{int128::Int128, int_wrapper::IntWrapper};
#[proc_macro_derive(Ordinalize, attributes(ordinalize))]
pub fn ordinalize_derive(input: TokenStream) -> TokenStream {
struct ConstMember {
vis: Option<Visibility>,
ident: Ident,
meta: Vec<Meta>,
function: bool,
}
impl Parse for ConstMember {
#[inline]
fn parse(input: ParseStream) -> syn::Result<Self> {
let vis = input.parse::<Visibility>().ok();
let _ = input.parse::<Token![const]>();
let function = input.parse::<Token![fn]>().is_ok();
let ident = input.parse::<Ident>()?;
let mut meta = Vec::new();
if !input.is_empty() {
input.parse::<Token![,]>()?;
if !input.is_empty() {
let result = Punctuated::<Meta, Token![,]>::parse_terminated(input)?;
let mut has_inline = false;
for m in result {
if m.path().is_ident("inline") {
has_inline = true;
}
meta.push(m);
}
if !has_inline {
meta.push(syn::parse_str("inline")?);
}
}
}
Ok(Self {
vis,
ident,
meta,
function,
})
}
}
struct ConstFunctionMember {
vis: Option<Visibility>,
ident: Ident,
meta: Vec<Meta>,
}
impl Parse for ConstFunctionMember {
#[inline]
fn parse(input: ParseStream) -> syn::Result<Self> {
let vis = input.parse::<Visibility>().ok();
let _ = input.parse::<Token![const]>();
input.parse::<Token![fn]>()?;
let ident = input.parse::<Ident>()?;
let mut meta = Vec::new();
if !input.is_empty() {
input.parse::<Token![,]>()?;
if !input.is_empty() {
let result = Punctuated::<Meta, Token![,]>::parse_terminated(input)?;
let mut has_inline = false;
for m in result {
if m.path().is_ident("inline") {
has_inline = true;
}
meta.push(m);
}
if !has_inline {
meta.push(syn::parse_str("inline")?);
}
}
}
Ok(Self {
vis,
ident,
meta,
})
}
}
struct MyDeriveInput {
ast: DeriveInput,
variant_type: VariantType,
values: Vec<IntWrapper>,
variant_idents: Vec<Ident>,
use_constant_counter: bool,
enable_trait: bool,
enable_variant_count: Option<ConstMember>,
enable_variants: Option<ConstMember>,
enable_values: Option<ConstMember>,
enable_from_ordinal_unsafe: Option<ConstFunctionMember>,
enable_from_ordinal: Option<ConstFunctionMember>,
enable_ordinal: Option<ConstFunctionMember>,
}
impl Parse for MyDeriveInput {
fn parse(input: ParseStream) -> syn::Result<Self> {
let ast = input.parse::<DeriveInput>()?;
let mut variant_type = VariantType::default();
let mut enable_trait = cfg!(feature = "traits");
let mut enable_variant_count = None;
let mut enable_variants = None;
let mut enable_values = None;
let mut enable_from_ordinal_unsafe = None;
let mut enable_from_ordinal = None;
let mut enable_ordinal = None;
for attr in ast.attrs.iter() {
let path = attr.path();
if let Some(ident) = path.get_ident() {
match ident.to_string().as_str() {
"repr" => {
// #[repr(u8)], #[repr(u16)], ..., etc.
if let Meta::List(list) = &attr.meta {
let result = list.parse_args_with(
Punctuated::<Ident, Token![,]>::parse_terminated,
)?;
if let Some(value) = result.into_iter().next() {
variant_type = VariantType::from_str(value.to_string());
}
}
break;
},
"ordinalize" => {
if let Meta::List(list) = &attr.meta {
let result = list.parse_args_with(
Punctuated::<Meta, Token![,]>::parse_terminated,
)?;
for meta in result {
let path = meta.path();
if let Some(ident) = path.get_ident() {
match ident.to_string().as_str() {
"impl_trait" => {
if let Meta::NameValue(meta) = &meta {
if let Expr::Lit(lit) = &meta.value {
if let Lit::Bool(value) = &lit.lit {
if cfg!(feature = "traits") {
enable_trait = value.value;
}
} else {
return Err(
panic::bool_attribute_usage(
ident,
ident.span(),
),
);
}
} else {
return Err(panic::bool_attribute_usage(
ident,
ident.span(),
));
}
} else {
return Err(panic::bool_attribute_usage(
ident,
ident.span(),
));
}
},
"variant_count" => {
if let Meta::List(list) = &meta {
enable_variant_count = Some(list.parse_args()?);
} else {
return Err(panic::list_attribute_usage(
ident,
ident.span(),
));
}
},
"variants" => {
if let Meta::List(list) = &meta {
enable_variants = Some(list.parse_args()?);
} else {
return Err(panic::list_attribute_usage(
ident,
ident.span(),
));
}
},
"values" => {
if let Meta::List(list) = &meta {
enable_values = Some(list.parse_args()?);
} else {
return Err(panic::list_attribute_usage(
ident,
ident.span(),
));
}
},
"from_ordinal_unsafe" => {
if let Meta::List(list) = &meta {
enable_from_ordinal_unsafe =
Some(list.parse_args()?);
} else {
return Err(panic::list_attribute_usage(
ident,
ident.span(),
));
}
},
"from_ordinal" => {
if let Meta::List(list) = &meta {
enable_from_ordinal = Some(list.parse_args()?);
} else {
return Err(panic::list_attribute_usage(
ident,
ident.span(),
));
}
},
"ordinal" => {
if let Meta::List(list) = &meta {
enable_ordinal = Some(list.parse_args()?);
} else {
return Err(panic::list_attribute_usage(
ident,
ident.span(),
));
}
},
_ => {
return Err(panic::sub_attributes_for_ordinalize(
ident.span(),
));
},
}
} else {
return Err(panic::list_attribute_usage(
ident,
ident.span(),
));
}
}
} else {
return Err(panic::list_attribute_usage(ident, ident.span()));
}
},
_ => (),
}
}
}
let name = &ast.ident;
if let Data::Enum(data) = &ast.data {
let variant_count = data.variants.len();
if variant_count == 0 {
return Err(panic::no_variant(name.span()));
}
let mut values: Vec<IntWrapper> = Vec::with_capacity(variant_count);
let mut variant_idents: Vec<Ident> = Vec::with_capacity(variant_count);
let mut use_constant_counter = false;
if let VariantType::NonDetermined = variant_type {
let mut min = i128::MAX;
let mut max = i128::MIN;
let mut counter = 0;
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) => {
if let Lit::Int(lit) = &lit.lit {
counter = lit.base10_parse().map_err(|error| {
syn::Error::new(lit.span(), error)
})?;
} else {
return Err(panic::unsupported_discriminant(
lit.span(),
));
}
},
Expr::Unary(unary) => {
if let UnOp::Neg(_) = unary.op {
match unary.expr.as_ref() {
Expr::Lit(lit) => {
if let Lit::Int(lit) = &lit.lit {
match lit.base10_parse::<i128>() {
Ok(i) => {
counter = -i;
},
Err(error) => {
// overflow
if lit.base10_digits() == "170141183460469231731687303715884105728" {
counter = i128::MIN;
} else {
return Err(syn::Error::new(lit.span(), error));
}
},
}
} else {
return Err(panic::unsupported_discriminant(lit.span()));
}
},
Expr::Path(_)
| Expr::Cast(_)
| Expr::Binary(_)
| Expr::Call(_) => {
return Err(panic::constant_variable_on_non_determined_size_enum(unary.expr.span()))
},
_ => return Err(panic::unsupported_discriminant(unary.expr.span())),
}
} else {
return Err(panic::unsupported_discriminant(
unary.op.span(),
));
}
},
Expr::Path(_)
| Expr::Cast(_)
| Expr::Binary(_)
| Expr::Call(_) => {
return Err(
panic::constant_variable_on_non_determined_size_enum(
exp.span(),
),
)
},
_ => return Err(panic::unsupported_discriminant(exp.span())),
}
};
if min > counter {
min = counter;
}
if max < counter {
max = counter;
}
variant_idents.push(variant.ident.clone());
values.push(IntWrapper::from(counter));
counter = counter.saturating_add(1);
} else {
return Err(panic::not_unit_variant(variant.span()));
}
}
if min >= i8::MIN as i128 && max <= i8::MAX as i128 {
variant_type = VariantType::I8;
} else if min >= i16::MIN as i128 && max <= i16::MAX as i128 {
variant_type = VariantType::I16;
} else if min >= i32::MIN as i128 && max <= i32::MAX as i128 {
variant_type = VariantType::I32;
} else if min >= i64::MIN as i128 && max <= i64::MAX as i128 {
variant_type = VariantType::I64;
} else {
variant_type = VariantType::I128;
}
} else {
let mut counter = Int128::ZERO;
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) => {
if let Lit::Int(lit) = &lit.lit {
counter = lit.base10_parse().map_err(|error| {
syn::Error::new(lit.span(), error)
})?;
values.push(IntWrapper::from(counter));
counter.inc();
last_exp = None;
} else {
return Err(panic::unsupported_discriminant(
lit.span(),
));
}
},
Expr::Unary(unary) => {
if let UnOp::Neg(_) = unary.op {
match unary.expr.as_ref() {
Expr::Lit(lit) => {
if let Lit::Int(lit) = &lit.lit {
counter = -lit.base10_parse().map_err(
|error| {
syn::Error::new(lit.span(), error)
},
)?;
values.push(IntWrapper::from(counter));
counter.inc();
last_exp = None;
} else {
return Err(
panic::unsupported_discriminant(
lit.span(),
),
);
}
},
Expr::Path(_) => {
values.push(IntWrapper::from((exp, 0)));
last_exp = Some(exp);
constant_counter = 1;
},
Expr::Cast(_) | Expr::Binary(_) | Expr::Call(_) => {
values.push(IntWrapper::from((exp, 0)));
last_exp = Some(exp);
constant_counter = 1;
use_constant_counter = true;
},
_ => {
return Err(panic::unsupported_discriminant(
exp.span(),
));
},
}
} else {
return Err(panic::unsupported_discriminant(
unary.op.span(),
));
}
},
Expr::Path(_) => {
values.push(IntWrapper::from((exp, 0)));
last_exp = Some(exp);
constant_counter = 1;
},
Expr::Cast(_) | Expr::Binary(_) | Expr::Call(_) => {
values.push(IntWrapper::from((exp, 0)));
last_exp = Some(exp);
constant_counter = 1;
use_constant_counter = true;
},
_ => return Err(panic::unsupported_discriminant(exp.span())),
}
} else if let Some(exp) = last_exp {
values.push(IntWrapper::from((exp, constant_counter)));
constant_counter += 1;
use_constant_counter = true;
} else {
values.push(IntWrapper::from(counter));
counter.inc();
}
variant_idents.push(variant.ident.clone());
} else {
return Err(panic::not_unit_variant(variant.span()));
}
}
}
Ok(MyDeriveInput {
ast,
variant_type,
values,
variant_idents,
use_constant_counter,
enable_trait,
enable_variant_count,
enable_variants,
enable_values,
enable_from_ordinal_unsafe,
enable_from_ordinal,
enable_ordinal,
})
} else {
Err(panic::not_enum(ast.ident.span()))
}
}
}
// Parse the token stream
let derive_input = parse_macro_input!(input as MyDeriveInput);
let MyDeriveInput {
ast,
variant_type,
values,
variant_idents,
use_constant_counter,
enable_trait,
enable_variant_count,
enable_variants,
enable_values,
enable_ordinal,
enable_from_ordinal_unsafe,
enable_from_ordinal,
} = derive_input;
// Get the identifier of the type.
let name = &ast.ident;
let variant_count = values.len();
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
// Build the code
let mut expanded = proc_macro2::TokenStream::new();
if enable_trait {
#[cfg(feature = "traits")]
{
let from_ordinal_unsafe = if variant_count == 1 {
let variant_ident = &variant_idents[0];
quote! {
#[inline]
unsafe fn from_ordinal_unsafe(_number: #variant_type) -> Self {
Self::#variant_ident
}
}
} else {
quote! {
#[inline]
unsafe fn from_ordinal_unsafe(number: #variant_type) -> Self {
::core::mem::transmute(number)
}
}
};
let from_ordinal = if use_constant_counter {
quote! {
#[inline]
fn from_ordinal(number: #variant_type) -> Option<Self> {
if false {
unreachable!()
} #( else if number == #values {
Some(Self::#variant_idents)
} )* else {
None
}
}
}
} else {
quote! {
#[inline]
fn from_ordinal(number: #variant_type) -> Option<Self> {
match number{
#(
#values => Some(Self::#variant_idents),
)*
_ => None
}
}
}
};
expanded.extend(quote! {
impl #impl_generics Ordinalize for #name #ty_generics #where_clause {
type VariantType = #variant_type;
const VARIANT_COUNT: usize = #variant_count;
const VARIANTS: &'static [Self] = &[#( Self::#variant_idents, )*];
const VALUES: &'static [#variant_type] = &[#( #values, )*];
#[inline]
fn ordinal(&self) -> #variant_type {
match self {
#(
Self::#variant_idents => #values,
)*
}
}
#from_ordinal_unsafe
#from_ordinal
}
});
}
}
let mut expanded_2 = proc_macro2::TokenStream::new();
if let Some(ConstMember {
vis,
ident,
meta,
function,
}) = enable_variant_count
{
expanded_2.extend(if function {
quote! {
#(#[#meta])*
#vis const fn #ident () -> usize {
#variant_count
}
}
} else {
quote! {
#(#[#meta])*
#vis const #ident: usize = #variant_count;
}
});
}
if let Some(ConstMember {
vis,
ident,
meta,
function,
}) = enable_variants
{
expanded_2.extend(if function {
quote! {
#(#[#meta])*
#vis const fn #ident () -> [Self; #variant_count] {
[#( Self::#variant_idents, )*]
}
}
} else {
quote! {
#(#[#meta])*
#vis const #ident: [Self; #variant_count] = [#( Self::#variant_idents, )*];
}
});
}
if let Some(ConstMember {
vis,
ident,
meta,
function,
}) = enable_values
{
expanded_2.extend(if function {
quote! {
#(#[#meta])*
#vis const fn #ident () -> [#variant_type; #variant_count] {
[#( #values, )*]
}
}
} else {
quote! {
#(#[#meta])*
#vis const #ident: [#variant_type; #variant_count] = [#( #values, )*];
}
});
}
if let Some(ConstFunctionMember {
vis,
ident,
meta,
}) = enable_from_ordinal_unsafe
{
let from_ordinal_unsafe = if variant_count == 1 {
let variant_ident = &variant_idents[0];
quote! {
#(#[#meta])*
#vis const unsafe fn #ident (_number: #variant_type) -> Self {
Self::#variant_ident
}
}
} else {
quote! {
#(#[#meta])*
#vis const unsafe fn #ident (number: #variant_type) -> Self {
::core::mem::transmute(number)
}
}
};
expanded_2.extend(from_ordinal_unsafe);
}
if let Some(ConstFunctionMember {
vis,
ident,
meta,
}) = enable_from_ordinal
{
let from_ordinal = if use_constant_counter {
quote! {
#(#[#meta])*
#vis const fn #ident (number: #variant_type) -> Option<Self> {
if false {
unreachable!()
} #( else if number == #values {
Some(Self::#variant_idents)
} )* else {
None
}
}
}
} else {
quote! {
#(#[#meta])*
#vis const fn #ident (number: #variant_type) -> Option<Self> {
match number{
#(
#values => Some(Self::#variant_idents),
)*
_ => None
}
}
}
};
expanded_2.extend(from_ordinal);
}
if let Some(ConstFunctionMember {
vis,
ident,
meta,
}) = enable_ordinal
{
expanded_2.extend(quote! {
#(#[#meta])*
#vis const fn #ident (&self) -> #variant_type {
match self {
#(
Self::#variant_idents => #values,
)*
}
}
});
}
if !expanded_2.is_empty() {
expanded.extend(quote! {
impl #impl_generics #name #ty_generics #where_clause {
#expanded_2
}
});
}
expanded.into()
}

View File

@@ -0,0 +1,81 @@
use core::fmt::{self, Display, Formatter};
use proc_macro2::Span;
use syn::Ident;
struct DisplayStringSlice<'a>(&'a [&'static str]);
impl<'a> Display for DisplayStringSlice<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
for &s in self.0 {
f.write_str("\n ")?;
f.write_str(s)?;
}
Ok(())
}
}
#[inline]
pub(crate) fn not_enum(span: Span) -> syn::Error {
syn::Error::new(span, "only enums can be ordinalized")
}
#[inline]
pub(crate) fn no_variant(span: Span) -> syn::Error {
syn::Error::new(span, "an ordinalized enum needs to have at least one variant")
}
#[inline]
pub(crate) fn not_unit_variant(span: Span) -> syn::Error {
syn::Error::new(span, "an ordinalized enum can only have unit variants")
}
#[inline]
pub(crate) fn unsupported_discriminant(span: Span) -> syn::Error {
syn::Error::new(
span,
"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(crate) fn constant_variable_on_non_determined_size_enum(span: Span) -> syn::Error {
syn::Error::new(
span,
"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",
)
}
#[inline]
pub fn list_attribute_usage(name: &Ident, span: Span) -> syn::Error {
syn::Error::new(span, format!("the `{name}` attribute should be a list"))
}
#[inline]
pub(crate) fn bool_attribute_usage(name: &Ident, span: Span) -> syn::Error {
syn::Error::new(
span,
format!("the `{name}` attribute should be a name-value pair. The value type is boolean"),
)
}
#[inline]
pub(crate) fn sub_attributes_for_ordinalize(span: Span) -> syn::Error {
syn::Error::new(
span,
format!(
"available sub-attributes for the `ordinalize` attribute:{}",
DisplayStringSlice(&[
"impl_trait",
"variant_count",
"variants",
"values",
"ordinal",
"from_ordinal_unsafe",
"from_ordinal",
])
),
)
}

View File

@@ -0,0 +1,75 @@
use proc_macro2::{Ident, Span, TokenStream};
use quote::{ToTokens, TokenStreamExt};
#[derive(Debug)]
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: AsRef<str>>(s: S) -> VariantType {
let s = s.as_ref();
match s {
"i8" => VariantType::I8,
"i16" => VariantType::I16,
"i32" => VariantType::I32,
"i64" => VariantType::I64,
"i128" => VariantType::I128,
"isize" => VariantType::ISize,
"u8" => VariantType::U8,
"u16" => VariantType::U16,
"u32" => VariantType::U32,
"u64" => VariantType::U64,
"u128" => VariantType::U128,
"usize" => VariantType::USize,
_ => 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()));
}
}