summaryrefslogtreecommitdiffstats
path: root/vendor/strum_macros/src/macros/strings
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:25 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:25 +0000
commit5363f350887b1e5b5dd21a86f88c8af9d7fea6da (patch)
tree35ca005eb6e0e9a1ba3bb5dbc033209ad445dc17 /vendor/strum_macros/src/macros/strings
parentAdding debian version 1.66.0+dfsg1-1. (diff)
downloadrustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.tar.xz
rustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/strum_macros/src/macros/strings')
-rw-r--r--vendor/strum_macros/src/macros/strings/as_ref_str.rs117
-rw-r--r--vendor/strum_macros/src/macros/strings/display.rs51
-rw-r--r--vendor/strum_macros/src/macros/strings/from_string.rs180
-rw-r--r--vendor/strum_macros/src/macros/strings/mod.rs4
-rw-r--r--vendor/strum_macros/src/macros/strings/to_string.rs51
5 files changed, 403 insertions, 0 deletions
diff --git a/vendor/strum_macros/src/macros/strings/as_ref_str.rs b/vendor/strum_macros/src/macros/strings/as_ref_str.rs
new file mode 100644
index 000000000..4dfdc4b80
--- /dev/null
+++ b/vendor/strum_macros/src/macros/strings/as_ref_str.rs
@@ -0,0 +1,117 @@
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::{parse_quote, Data, DeriveInput, Fields};
+
+use crate::helpers::{non_enum_error, HasStrumVariantProperties, HasTypeProperties};
+
+fn get_arms(ast: &DeriveInput) -> syn::Result<Vec<TokenStream>> {
+ let name = &ast.ident;
+ let mut arms = Vec::new();
+ let variants = match &ast.data {
+ Data::Enum(v) => &v.variants,
+ _ => return Err(non_enum_error()),
+ };
+
+ let type_properties = ast.get_type_properties()?;
+
+ for variant in variants {
+ let ident = &variant.ident;
+ let variant_properties = variant.get_variant_properties()?;
+
+ if variant_properties.disabled.is_some() {
+ continue;
+ }
+
+ // Look at all the serialize attributes.
+ // Use `to_string` attribute (not `as_ref_str` or something) to keep things consistent
+ // (i.e. always `enum.as_ref().to_string() == enum.to_string()`).
+ let output = variant_properties.get_preferred_name(type_properties.case_style);
+ let params = match variant.fields {
+ Fields::Unit => quote! {},
+ Fields::Unnamed(..) => quote! { (..) },
+ Fields::Named(..) => quote! { {..} },
+ };
+
+ arms.push(quote! { #name::#ident #params => #output });
+ }
+
+ if arms.len() < variants.len() {
+ arms.push(quote! {
+ _ => panic!(
+ "AsRef::<str>::as_ref() or AsStaticRef::<str>::as_static() \
+ called on disabled variant.",
+ )
+ });
+ }
+
+ Ok(arms)
+}
+
+pub fn as_ref_str_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
+ let name = &ast.ident;
+ let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
+ let arms = get_arms(ast)?;
+ Ok(quote! {
+ impl #impl_generics ::core::convert::AsRef<str> for #name #ty_generics #where_clause {
+ fn as_ref(&self) -> &str {
+ match *self {
+ #(#arms),*
+ }
+ }
+ }
+ })
+}
+
+pub enum GenerateTraitVariant {
+ AsStaticStr,
+ From,
+}
+
+pub fn as_static_str_inner(
+ ast: &DeriveInput,
+ trait_variant: &GenerateTraitVariant,
+) -> syn::Result<TokenStream> {
+ let name = &ast.ident;
+ let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
+ let arms = get_arms(ast)?;
+ let type_properties = ast.get_type_properties()?;
+ let strum_module_path = type_properties.crate_module_path();
+
+ let mut generics = ast.generics.clone();
+ generics
+ .params
+ .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();
+
+ Ok(match trait_variant {
+ GenerateTraitVariant::AsStaticStr => quote! {
+ impl #impl_generics #strum_module_path::AsStaticRef<str> for #name #ty_generics #where_clause {
+ fn as_static(&self) -> &'static str {
+ match *self {
+ #(#arms),*
+ }
+ }
+ }
+ },
+ GenerateTraitVariant::From => quote! {
+ impl #impl_generics ::core::convert::From<#name #ty_generics> for &'static str #where_clause {
+ fn from(x: #name #ty_generics) -> &'static str {
+ match x {
+ #(#arms2),*
+ }
+ }
+ }
+ impl #impl_generics2 ::core::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),*
+ }
+ }
+ }
+ },
+ })
+}
diff --git a/vendor/strum_macros/src/macros/strings/display.rs b/vendor/strum_macros/src/macros/strings/display.rs
new file mode 100644
index 000000000..82a34b0df
--- /dev/null
+++ b/vendor/strum_macros/src/macros/strings/display.rs
@@ -0,0 +1,51 @@
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::{Data, DeriveInput, Fields};
+
+use crate::helpers::{non_enum_error, HasStrumVariantProperties, HasTypeProperties};
+
+pub fn display_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
+ let name = &ast.ident;
+ let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
+ let variants = match &ast.data {
+ Data::Enum(v) => &v.variants,
+ _ => return Err(non_enum_error()),
+ };
+
+ let type_properties = ast.get_type_properties()?;
+
+ let mut arms = Vec::new();
+ for variant in variants {
+ let ident = &variant.ident;
+ let variant_properties = variant.get_variant_properties()?;
+
+ if variant_properties.disabled.is_some() {
+ continue;
+ }
+
+ // Look at all the serialize attributes.
+ let output = variant_properties.get_preferred_name(type_properties.case_style);
+
+ let params = match variant.fields {
+ Fields::Unit => quote! {},
+ Fields::Unnamed(..) => quote! { (..) },
+ Fields::Named(..) => quote! { {..} },
+ };
+
+ arms.push(quote! { #name::#ident #params => f.pad(#output) });
+ }
+
+ if arms.len() < variants.len() {
+ arms.push(quote! { _ => panic!("fmt() called on disabled variant.") });
+ }
+
+ Ok(quote! {
+ impl #impl_generics ::core::fmt::Display for #name #ty_generics #where_clause {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::result::Result<(), ::core::fmt::Error> {
+ match *self {
+ #(#arms),*
+ }
+ }
+ }
+ })
+}
diff --git a/vendor/strum_macros/src/macros/strings/from_string.rs b/vendor/strum_macros/src/macros/strings/from_string.rs
new file mode 100644
index 000000000..2d2559174
--- /dev/null
+++ b/vendor/strum_macros/src/macros/strings/from_string.rs
@@ -0,0 +1,180 @@
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::{Data, DeriveInput, Fields};
+
+use crate::helpers::{
+ non_enum_error, occurrence_error, HasStrumVariantProperties, HasTypeProperties,
+};
+
+pub fn from_string_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
+ let name = &ast.ident;
+ let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
+ let variants = match &ast.data {
+ Data::Enum(v) => &v.variants,
+ _ => return Err(non_enum_error()),
+ };
+
+ let type_properties = ast.get_type_properties()?;
+ let strum_module_path = type_properties.crate_module_path();
+
+ let mut default_kw = None;
+ let mut default =
+ quote! { ::core::result::Result::Err(#strum_module_path::ParseError::VariantNotFound) };
+
+ let mut phf_exact_match_arms = Vec::new();
+ let mut standard_match_arms = Vec::new();
+ for variant in variants {
+ let ident = &variant.ident;
+ let variant_properties = variant.get_variant_properties()?;
+
+ if variant_properties.disabled.is_some() {
+ continue;
+ }
+
+ if let Some(kw) = variant_properties.default {
+ if let Some(fst_kw) = default_kw {
+ return Err(occurrence_error(fst_kw, kw, "default"));
+ }
+
+ match &variant.fields {
+ Fields::Unnamed(fields) if fields.unnamed.len() == 1 => {}
+ _ => {
+ return Err(syn::Error::new_spanned(
+ variant,
+ "Default only works on newtype structs with a single String field",
+ ))
+ }
+ }
+
+ default_kw = Some(kw);
+ default = quote! {
+ ::core::result::Result::Ok(#name::#ident(s.into()))
+ };
+ continue;
+ }
+
+ let params = match &variant.fields {
+ Fields::Unit => quote! {},
+ Fields::Unnamed(fields) => {
+ let defaults =
+ ::core::iter::repeat(quote!(Default::default())).take(fields.unnamed.len());
+ quote! { (#(#defaults),*) }
+ }
+ Fields::Named(fields) => {
+ let fields = fields
+ .named
+ .iter()
+ .map(|field| field.ident.as_ref().unwrap());
+ quote! { {#(#fields: Default::default()),*} }
+ }
+ };
+
+ let is_ascii_case_insensitive = variant_properties
+ .ascii_case_insensitive
+ .unwrap_or(type_properties.ascii_case_insensitive);
+
+ // If we don't have any custom variants, add the default serialized name.
+ for serialization in variant_properties.get_serializations(type_properties.case_style) {
+ if type_properties.use_phf {
+ phf_exact_match_arms.push(quote! { #serialization => #name::#ident #params, });
+
+ if is_ascii_case_insensitive {
+ // Store the lowercase and UPPERCASE variants in the phf map to capture
+ let ser_string = serialization.value();
+
+ let lower =
+ syn::LitStr::new(&ser_string.to_ascii_lowercase(), serialization.span());
+ let upper =
+ syn::LitStr::new(&ser_string.to_ascii_uppercase(), serialization.span());
+ phf_exact_match_arms.push(quote! { #lower => #name::#ident #params, });
+ phf_exact_match_arms.push(quote! { #upper => #name::#ident #params, });
+ standard_match_arms.push(quote! { s if s.eq_ignore_ascii_case(#serialization) => #name::#ident #params, });
+ }
+ } else {
+ standard_match_arms.push(if !is_ascii_case_insensitive {
+ quote! { #serialization => #name::#ident #params, }
+ } else {
+ quote! { s if s.eq_ignore_ascii_case(#serialization) => #name::#ident #params, }
+ });
+ }
+ }
+ }
+
+ let phf_body = if phf_exact_match_arms.is_empty() {
+ quote!()
+ } else {
+ quote! {
+ use #strum_module_path::_private_phf_reexport_for_macro_if_phf_feature as phf;
+ static PHF: phf::Map<&'static str, #name> = phf::phf_map! {
+ #(#phf_exact_match_arms)*
+ };
+ if let Some(value) = PHF.get(s).cloned() {
+ return ::core::result::Result::Ok(value);
+ }
+ }
+ };
+ let standard_match_body = if standard_match_arms.is_empty() {
+ default
+ } else {
+ quote! {
+ ::core::result::Result::Ok(match s {
+ #(#standard_match_arms)*
+ _ => return #default,
+ })
+ }
+ };
+
+ let from_str = quote! {
+ #[allow(clippy::use_self)]
+ impl #impl_generics ::core::str::FromStr for #name #ty_generics #where_clause {
+ type Err = #strum_module_path::ParseError;
+ fn from_str(s: &str) -> ::core::result::Result< #name #ty_generics , <Self as ::core::str::FromStr>::Err> {
+ #phf_body
+ #standard_match_body
+ }
+ }
+ };
+
+ let try_from_str = try_from_str(
+ name,
+ &impl_generics,
+ &ty_generics,
+ where_clause,
+ &strum_module_path,
+ );
+
+ Ok(quote! {
+ #from_str
+ #try_from_str
+ })
+}
+
+#[rustversion::before(1.34)]
+fn try_from_str(
+ _name: &proc_macro2::Ident,
+ _impl_generics: &syn::ImplGenerics,
+ _ty_generics: &syn::TypeGenerics,
+ _where_clause: Option<&syn::WhereClause>,
+ _strum_module_path: &syn::Path,
+) -> TokenStream {
+ Default::default()
+}
+
+#[rustversion::since(1.34)]
+fn try_from_str(
+ name: &proc_macro2::Ident,
+ impl_generics: &syn::ImplGenerics,
+ ty_generics: &syn::TypeGenerics,
+ where_clause: Option<&syn::WhereClause>,
+ strum_module_path: &syn::Path,
+) -> TokenStream {
+ quote! {
+ #[allow(clippy::use_self)]
+ impl #impl_generics ::core::convert::TryFrom<&str> for #name #ty_generics #where_clause {
+ type Error = #strum_module_path::ParseError;
+ fn try_from(s: &str) -> ::core::result::Result< #name #ty_generics , <Self as ::core::convert::TryFrom<&str>>::Error> {
+ ::core::str::FromStr::from_str(s)
+ }
+ }
+ }
+}
diff --git a/vendor/strum_macros/src/macros/strings/mod.rs b/vendor/strum_macros/src/macros/strings/mod.rs
new file mode 100644
index 000000000..e416f4b3b
--- /dev/null
+++ b/vendor/strum_macros/src/macros/strings/mod.rs
@@ -0,0 +1,4 @@
+pub mod as_ref_str;
+pub mod display;
+pub mod from_string;
+pub mod to_string;
diff --git a/vendor/strum_macros/src/macros/strings/to_string.rs b/vendor/strum_macros/src/macros/strings/to_string.rs
new file mode 100644
index 000000000..7e4c48380
--- /dev/null
+++ b/vendor/strum_macros/src/macros/strings/to_string.rs
@@ -0,0 +1,51 @@
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::{Data, DeriveInput, Fields};
+
+use crate::helpers::{non_enum_error, HasStrumVariantProperties, HasTypeProperties};
+
+pub fn to_string_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
+ let name = &ast.ident;
+ let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
+ let variants = match &ast.data {
+ Data::Enum(v) => &v.variants,
+ _ => return Err(non_enum_error()),
+ };
+
+ let type_properties = ast.get_type_properties()?;
+ let mut arms = Vec::new();
+ for variant in variants {
+ let ident = &variant.ident;
+ let variant_properties = variant.get_variant_properties()?;
+
+ if variant_properties.disabled.is_some() {
+ continue;
+ }
+
+ // Look at all the serialize attributes.
+ let output = variant_properties.get_preferred_name(type_properties.case_style);
+
+ let params = match variant.fields {
+ Fields::Unit => quote! {},
+ Fields::Unnamed(..) => quote! { (..) },
+ Fields::Named(..) => quote! { {..} },
+ };
+
+ arms.push(quote! { #name::#ident #params => ::std::string::String::from(#output) });
+ }
+
+ if arms.len() < variants.len() {
+ arms.push(quote! { _ => panic!("to_string() called on disabled variant.") });
+ }
+
+ Ok(quote! {
+ #[allow(clippy::use_self)]
+ impl #impl_generics ::std::string::ToString for #name #ty_generics #where_clause {
+ fn to_string(&self) -> ::std::string::String {
+ match *self {
+ #(#arms),*
+ }
+ }
+ }
+ })
+}