diff --git a/examples/feature_showcase/choice_parameter.rs b/examples/feature_showcase/choice_parameter.rs index 932eb16495c..17d0953a4d4 100644 --- a/examples/feature_showcase/choice_parameter.rs +++ b/examples/feature_showcase/choice_parameter.rs @@ -27,7 +27,7 @@ pub async fn choice( // // Limitations: due to macro limitations (partially self-imposed, partially external), poise // currently does not support Options parameters, and only supports parameter types that can be -// constructed from a literal (https://doc.rust-lang.org/reference/expressions/literal-expr.html). +// constructed from a literal which can be converted to a string at compile time. #[poise::command(slash_command)] pub async fn inline_choice( diff --git a/macros/src/command/slash.rs b/macros/src/command/slash.rs index f635006c71c..3a56fee4327 100644 --- a/macros/src/command/slash.rs +++ b/macros/src/command/slash.rs @@ -1,10 +1,26 @@ use super::Invocation; use crate::util::{ extract_type_parameter, iter_tuple_2_to_hash_map, tuple_2_iter_deref, wrap_option_to_string, + List, }; use quote::format_ident; use syn::spanned::Spanned as _; +fn lit_to_string(lit: &syn::Lit) -> Result { + match lit { + syn::Lit::Str(lit_str) => Ok(lit_str.value()), + syn::Lit::Char(lit_char) => Ok(lit_char.value().to_string()), + syn::Lit::Int(lit_int) => Ok(lit_int.base10_digits().to_owned()), + syn::Lit::Float(lit_float) => Ok(lit_float.token().to_string()), + syn::Lit::Bool(lit_bool) => Ok(lit_bool.value.to_string()), + + _ => Err(syn::Error::new( + lit.span(), + "Inline choice must be convertable to a string at compile time", + )), + } +} + pub fn generate_parameters(inv: &Invocation) -> Result, syn::Error> { let mut parameter_structs = Vec::new(); for param in &inv.parameters { @@ -77,10 +93,14 @@ pub fn generate_parameters(inv: &Invocation) -> Result { - if let Some(choices) = ¶m.args.choices { - let choices = &choices.0; + if let Some(List(choices)) = ¶m.args.choices { + let choices = choices + .iter() + .map(lit_to_string) + .collect::, _>>()?; + quote::quote! { vec![#( ::poise::CommandParameterChoice { - name: ToString::to_string(&#choices), + name: String::from(#choices), localizations: Default::default(), __non_exhaustive: (), } ),*] }