summaryrefslogtreecommitdiff
path: root/vendor/enum-ordinalize-derive
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
committermo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
commit8cdfa445d6629ffef4cb84967ff7017654045bc2 (patch)
tree22f0b0907c024c78d26a731e2e1f5219407d8102 /vendor/enum-ordinalize-derive
parent4351c74c7c5f97156bc94d3a8549b9940ac80e3f (diff)
chore: add vendor directory
Diffstat (limited to 'vendor/enum-ordinalize-derive')
-rw-r--r--vendor/enum-ordinalize-derive/.cargo-checksum.json1
-rw-r--r--vendor/enum-ordinalize-derive/Cargo.toml53
-rw-r--r--vendor/enum-ordinalize-derive/LICENSE21
-rw-r--r--vendor/enum-ordinalize-derive/README.md20
-rw-r--r--vendor/enum-ordinalize-derive/src/int128.rs167
-rw-r--r--vendor/enum-ordinalize-derive/src/int_wrapper.rs57
-rw-r--r--vendor/enum-ordinalize-derive/src/lib.rs808
-rw-r--r--vendor/enum-ordinalize-derive/src/panic.rs83
-rw-r--r--vendor/enum-ordinalize-derive/src/variant_type.rs75
9 files changed, 1285 insertions, 0 deletions
diff --git a/vendor/enum-ordinalize-derive/.cargo-checksum.json b/vendor/enum-ordinalize-derive/.cargo-checksum.json
new file mode 100644
index 00000000..9eee33e6
--- /dev/null
+++ b/vendor/enum-ordinalize-derive/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"e08fa63e6cef52de7befa61700f0ebb389d803c778e0689a15a34506cbbb5e15","LICENSE":"dd0741aba702705d02da3e18fca5d3a27538fe6c983e9f09946e82ecfc59acab","README.md":"8f1ed96e3631c27e38af090ec060aefd4999d683fb3090786b46a8d1a2ed688e","src/int128.rs":"4dd502fa528d75a7f55bd17107e1ba1fc4a710025d10bbc24514fb56777f314a","src/int_wrapper.rs":"c16c57ab57f005b34a6776d07d3fb257380b99262701b3972c957fe9bcb698b5","src/lib.rs":"e9aab14cc9f279fbd66a1ff465f786c15ec1860cab14da3e9b64e879ee027680","src/panic.rs":"0d71b9e870d6e773f3d7f80884b34f21aa7ca12651498d666faea4afcee27cec","src/variant_type.rs":"3a4cc4107b7b91f061efc7deab437c05a973897b79c1babf73ec3d918d2b5fd9"},"package":"0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff"} \ No newline at end of file
diff --git a/vendor/enum-ordinalize-derive/Cargo.toml b/vendor/enum-ordinalize-derive/Cargo.toml
new file mode 100644
index 00000000..2aff73b4
--- /dev/null
+++ b/vendor/enum-ordinalize-derive/Cargo.toml
@@ -0,0 +1,53 @@
+# 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.60"
+name = "enum-ordinalize-derive"
+version = "4.3.1"
+include = [
+ "src/**/*",
+ "Cargo.toml",
+ "README.md",
+ "LICENSE",
+]
+description = "This crate provides a procedural macro that enables enums to not only obtain the ordinal values of their variants but also allows for the construction of enums from an ordinal value."
+homepage = "https://magiclen.org/enum-ordinalize"
+readme = "README.md"
+keywords = [
+ "enum",
+ "ordinal",
+ "ordinalize",
+ "number",
+]
+categories = [
+ "no-std",
+ "rust-patterns",
+]
+license = "MIT"
+repository = "https://github.com/magiclen/enum-ordinalize"
+
+[lib]
+proc-macro = true
+
+[dependencies.proc-macro2]
+version = "1"
+
+[dependencies.quote]
+version = "1"
+
+[dependencies.syn]
+version = "2"
+
+[features]
+default = []
+traits = []
diff --git a/vendor/enum-ordinalize-derive/LICENSE b/vendor/enum-ordinalize-derive/LICENSE
new file mode 100644
index 00000000..ba1efc6c
--- /dev/null
+++ b/vendor/enum-ordinalize-derive/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 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.
diff --git a/vendor/enum-ordinalize-derive/README.md b/vendor/enum-ordinalize-derive/README.md
new file mode 100644
index 00000000..a55369ab
--- /dev/null
+++ b/vendor/enum-ordinalize-derive/README.md
@@ -0,0 +1,20 @@
+Enum Ordinalize Derive
+====================
+
+[![CI](https://github.com/magiclen/enum-ordinalize/actions/workflows/ci.yml/badge.svg)](https://github.com/magiclen/enum-ordinalize/actions/workflows/ci.yml)
+
+This crate provides a procedural macro that 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.
+
+## Crates.io
+
+https://crates.io/crates/enum-ordinalize
+
+## Documentation
+
+https://docs.rs/enum-ordinalize
+
+## License
+
+[MIT](LICENSE) \ No newline at end of file
diff --git a/vendor/enum-ordinalize-derive/src/int128.rs b/vendor/enum-ordinalize-derive/src/int128.rs
new file mode 100644
index 00000000..755dcd7c
--- /dev/null
+++ b/vendor/enum-ordinalize-derive/src/int128.rs
@@ -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);
+ },
+ }
+ }
+}
diff --git a/vendor/enum-ordinalize-derive/src/int_wrapper.rs b/vendor/enum-ordinalize-derive/src/int_wrapper.rs
new file mode 100644
index 00000000..3747325d
--- /dev/null
+++ b/vendor/enum-ordinalize-derive/src/int_wrapper.rs
@@ -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));
+ }
+ },
+ }
+ }
+}
diff --git a/vendor/enum-ordinalize-derive/src/lib.rs b/vendor/enum-ordinalize-derive/src/lib.rs
new file mode 100644
index 00000000..5af4b2ca
--- /dev/null
+++ b/vendor/enum-ordinalize-derive/src/lib.rs
@@ -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()
+}
diff --git a/vendor/enum-ordinalize-derive/src/panic.rs b/vendor/enum-ordinalize-derive/src/panic.rs
new file mode 100644
index 00000000..5066656f
--- /dev/null
+++ b/vendor/enum-ordinalize-derive/src/panic.rs
@@ -0,0 +1,83 @@
+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"))
+ // use `name = name` to support Rust 1.56
+}
+
+#[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"),
+ )
+ // use `name = name` to support Rust 1.56
+}
+
+#[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",
+ ])
+ ),
+ )
+}
diff --git a/vendor/enum-ordinalize-derive/src/variant_type.rs b/vendor/enum-ordinalize-derive/src/variant_type.rs
new file mode 100644
index 00000000..70a9072f
--- /dev/null
+++ b/vendor/enum-ordinalize-derive/src/variant_type.rs
@@ -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()));
+ }
+}