-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement autocomplete models #9
Comments
I started working on an implementation in the |
How would you handle a case where there are multiple options on a command and any of them could be focused? In the example your decorator is a compile-time macro, so you wouldn't be able to shift to another field on the fly right? |
Yes, this could be a problem in these cases. Another implementation was proposed by @itohatweb on Discord: enum AutocompleteValue<T> {
None,
Focused(String),
Completed(T)
}
#[derive(CommandModel, Debug)]
#[command(partial = true)]
struct AutocompleteCmd {
num: AutocompleteValue<i32>,
} This would solve the problem, but the use would be a bit more tedious. But it also seems easier to implement, I'll try to look at this during the week. |
I'm currently manually handling this with something I saw @laralove143 do, though I modified it to make it generic. I think I'd add a focused field to this for more than one field needed during autocompletes though. #[derive(Clone, Debug)]
pub enum InteractionAutocompleteOption<T> {
/// The interaction is sent completely, as if a complete command.
Complete(T),
/// The interaction is sent partially, as if being autocompleted.
Partial(String),
} This is used on my individual command structs with a #[derive(Clone, Debug)]
pub struct AddCommand {
pub ship_model: InteractionAutocompleteOption<String>,
pub ship_name: Option<String>,
}
In the autocomplete case try_from returns the enum variant Partial, and in the command case try_from returns the Complete variant. I have to do all this manually, of course, and this command isn't even using twilight_interactions at all, but maybe this will give you some brainstorming power. |
Blocking on twilight-rs/twilight#1614 |
[EDIT] Nevermind I don't think this is a good idea lol I don't know how hard this would be, but would something like this be possible: #[derive(CommandModel, CreateCommand)]
#[command(name = "search", desc = "Search the web.")]
pub struct Hello {
#[command(autocomplete=true, desc="The service to use.")]
service: String,
#[command(autocomplete=true, desc="The query.")]
query: String,
#[command(autocomplete=true, desc="Maximum results to return.")]
max_results: Option<i32>,
} Then, you can match the InteractionCreate: int: InteractionCreate;
match int.0 {
Interaction::ApplicationCommand(data) => {
let cmd = Hello::from_interaction(data)?;
// Handle the cmd. All the fields are as they're defined
// on the struct.
}
Interaction::ApplicationCommandAutocomplete(data) => {
let cmd = from_autocomplete!(Hello, data);
// Create some sort of anonymous struct, kinda like
// AutocompleteData {
// command_parents: Vec<String> // 1 or 2 parents, if this command is a subcommand
// command_name: String,
// focused_field: String,
// focused_data: String,
// options: PartialCommand {
// service: AutocompleteValue<String>,
// query: AutocompleteValue<String>,
// max_results: AutocompleteValue<Option<i32>>,
// }
// }
// Where AutocompleteValue is
// enum AutoCompleteValue<T> {
// NoData, // No data yet
// Complete(T), // This field has been completed
// Focused(String), // This is the field currently being autocompleted
// }
}
} I have seen sqlx create anonymous structs, so I know that part is possible, but I don't know how hard it would be to create an anonymous struct from an existing struct, by changing the column types. This may be entirely impossible or just too much work, but I thought I'd share my idea anyways. |
Autocomplete are now supported in the It requires using the use twilight_interactions::command::{AutocompleteValue, CommandModel, ResolvedUser};
#[derive(CommandModel)]
#[command(autocomplete = true)]
struct HelloCommand {
message: AutocompleteValue<String>,
user: Option<ResolvedUser>,
} Autocomplete interactions are supported with the pub enum AutocompleteValue<T> {
None,
Focused(String),
Completed(T),
} Autocomplete interactions have some restrictions compared to "default" ones: all fields must be |
I found a way that's easy for my use case (where I don't need access to any of the variables). My command structs look like this: #[derive(CommandModel, CreateCommand)]
#[command(name="name", desc="desc")]
struct MyCommand {
/// Option name
#[command(autocomplete=true)]
option: String
} Will this still work after the next release? |
@CircuitSacul Autocomplete models are separate from the "normal" ones, it will not affect your existing models at all. |
Released with twilight-interactions 0.12.0 (full changelog). |
Autocomplete support has been removed in
twilight-interactions
0.10 because the existing implementation was incorrect. It is necessary to re-implement this feature in a next release.The main difference with regular command models is that autocomplete models receive partial and not validated data. In fact, some validation is performed client-side, but all fields, no matter their type, are sent by Discord as strings. Furthermore, all fields should be considered as optional except the current
focused
field.Proposed implementation
The implementation that seems most suitable is the creation of a new
AutocompleteModel
trait with associated derive macros. This trait would allow creating models of autocomplete interactions, with the support for afocused
attribute that specify which field expect to be focused (optional). It is also necessary to support subcommands.The text was updated successfully, but these errors were encountered: