Geoffrey-rs/geoffrey_bot/src/commands/selling.rs

128 lines
4.5 KiB
Rust

use crate::commands::bot_command::{BotCommand, CommandError};
use async_trait::async_trait;
use geoffrey_models::models::parameters::selling_params::{ItemSort, Order, SellingParams};
use geoffrey_models::models::response::selling_listing::SellingListing;
use reqwest::Method;
use serenity::client::Context;
use serenity::model::interactions::application_command::{
ApplicationCommand, ApplicationCommandInteraction, ApplicationCommandOptionType,
};
use serenity::model::prelude::application_command::ApplicationCommandInteractionDataOptionValue;
use std::fmt::Write;
use std::str::FromStr;
pub struct SellingCommand;
#[async_trait]
impl BotCommand for SellingCommand {
type ApiParams = SellingParams;
type ApiResp = Vec<SellingListing>;
fn command_name() -> String {
"selling".to_string()
}
fn request_type() -> Method {
Method::GET
}
async fn create_app_command(ctx: &Context) -> Result<ApplicationCommand, CommandError> {
let command = ApplicationCommand::create_global_application_command(&ctx.http, |command| {
command
.name(Self::command_name())
.description("Find items for sale.")
.create_option(|option| {
option
.name("query")
.description("Item to find")
.kind(ApplicationCommandOptionType::String)
.required(true)
})
.create_option(|option| {
option
.name("sort")
.description("How to sort items")
.kind(ApplicationCommandOptionType::String)
.add_string_choice(ItemSort::Price, ItemSort::Price)
.add_string_choice(ItemSort::Restock, ItemSort::Restock)
.required(false)
})
.create_option(|option| {
option
.name("order")
.description("Order of the item Search")
.kind(ApplicationCommandOptionType::String)
.add_string_choice(Order::Low, Order::Low)
.add_string_choice(Order::High, Order::High)
.required(false)
})
})
.await?;
Ok(command)
}
async fn process_arguments(
command_interaction: ApplicationCommandInteraction,
) -> Result<Self::ApiParams, CommandError> {
let options = command_interaction.data.options;
let mut query = String::new();
let mut sort = None;
let mut order = None;
if let Some(option) = options.get(0) {
let option = option.resolved.as_ref();
if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option {
query = s.clone();
} else {
return Err(CommandError::ArgumentParse("query".to_string()));
}
}
if let Some(option) = options.get(1) {
let option = option.resolved.as_ref();
if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option {
sort = Some(ItemSort::from_str(s).unwrap());
} else {
return Err(CommandError::ArgumentParse("sort".to_string()));
}
}
if let Some(option) = options.get(2) {
let option = option.resolved.as_ref();
if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option {
order = Some(Order::from_str(s).unwrap());
} else {
return Err(CommandError::ArgumentParse("order".to_string()));
}
}
Ok(SellingParams::new(query, sort, order))
}
fn build_response(resp: Self::ApiResp) -> String {
if resp.is_empty() {
"No shops were found selling that, maybe I should start selling it...".to_string()
} else {
let mut resp_str = String::new();
writeln!(resp_str, "The items match:").unwrap();
for item in resp {
writeln!(
resp_str,
"**{}**, {}D for {}: {} {}",
item.listing.item.name,
item.listing.count_per_price,
item.listing.count_per_price,
item.shop_name,
item.shop_loc
)
.unwrap();
}
resp_str
}
}
}