Skip to content

Commit

Permalink
Stop using serde_json::Value in AutocompleteChoice::value (serenity-r…
Browse files Browse the repository at this point in the history
…s#3000)

More type safe, more performant, less reliant on serde_json, what's not
to love!
  • Loading branch information
GnomedDev committed Nov 11, 2024
1 parent 2932daf commit c2fd6bd
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 34 deletions.
3 changes: 1 addition & 2 deletions examples/testing/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,7 @@ impl EventHandler for Handler {
i.create_response(
&ctx.http,
CreateInteractionResponse::Autocomplete(
CreateAutocompleteResponse::new()
.add_string_choice("suggestion", "suggestion"),
CreateAutocompleteResponse::new().add_choice("suggestion"),
),
)
.await
Expand Down
82 changes: 50 additions & 32 deletions src/builder/create_interaction_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,19 +280,59 @@ impl<'a> CreateInteractionResponseMessage<'a> {
super::button_and_select_menu_convenience_methods!(self.components);
}

#[derive(Clone, Debug, Serialize)]
#[serde(untagged)]
#[non_exhaustive]
#[must_use]
pub enum AutocompleteValue<'a> {
String(Cow<'a, str>),
Integer(u64),
Float(f64),
}

impl<'a> From<Cow<'a, str>> for AutocompleteValue<'a> {
fn from(value: Cow<'a, str>) -> Self {
Self::String(value)
}
}

impl From<String> for AutocompleteValue<'static> {
fn from(value: String) -> Self {
Self::String(Cow::Owned(value))
}
}

impl<'a> From<&'a str> for AutocompleteValue<'a> {
fn from(value: &'a str) -> Self {
Self::String(Cow::Borrowed(value))
}
}

impl From<u64> for AutocompleteValue<'static> {
fn from(value: u64) -> Self {
Self::Integer(value)
}
}

impl From<f64> for AutocompleteValue<'static> {
fn from(value: f64) -> Self {
Self::Float(value)
}
}

// Same as CommandOptionChoice according to Discord, see
// [Autocomplete docs](https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-autocomplete).
#[must_use]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Serialize)]
pub struct AutocompleteChoice<'a> {
pub name: Cow<'a, str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name_localizations: Option<HashMap<Cow<'a, str>, Cow<'a, str>>>,
pub value: Value,
pub value: AutocompleteValue<'a>,
}

impl<'a> AutocompleteChoice<'a> {
pub fn new(name: impl Into<Cow<'a, str>>, value: impl Into<Value>) -> Self {
pub fn new(name: impl Into<Cow<'a, str>>, value: impl Into<AutocompleteValue<'a>>) -> Self {
Self {
name: name.into(),
name_localizations: None,
Expand Down Expand Up @@ -343,36 +383,14 @@ impl<'a> CreateAutocompleteResponse<'a> {
self
}

/// Add an int autocomplete choice.
///
/// **Note**: There can be no more than 25 choices set. Name must be between 1 and 100
/// characters. Value must be between -2^53 and 2^53.
pub fn add_int_choice(self, name: impl Into<Cow<'a, str>>, value: i64) -> Self {
self.add_choice(AutocompleteChoice::new(name, value))
}

/// Adds a string autocomplete choice.
/// Add an autocomplete choice.
///
/// **Note**: There can be no more than 25 choices set. Name must be between 1 and 100
/// characters. Value must be up to 100 characters.
pub fn add_string_choice(
self,
name: impl Into<Cow<'a, str>>,
value: impl Into<Cow<'a, str>>,
) -> Self {
self.add_choice(AutocompleteChoice::new(name, value.into()))
}

/// Adds a number autocomplete choice.
///
/// **Note**: There can be no more than 25 choices set. Name must be between 1 and 100
/// characters. Value must be between -2^53 and 2^53.
pub fn add_number_choice(self, name: impl Into<Cow<'a, str>>, value: f64) -> Self {
self.add_choice(AutocompleteChoice::new(name, value))
}

fn add_choice(mut self, value: AutocompleteChoice<'a>) -> Self {
self.choices.to_mut().push(value);
/// # Limitations
/// - There can be no more than 25 choices set.
/// - Name must be between 1 and 100 characters.
/// - If value is an integer/float must be between -2^53 and 2^53.
pub fn add_choice(mut self, value: impl Into<AutocompleteChoice<'a>>) -> Self {
self.choices.to_mut().push(value.into());
self
}

Expand Down

0 comments on commit c2fd6bd

Please sign in to comment.