Skip to content

Commit

Permalink
Merge pull request #135 from jontze/chore/reduce-command-boilerplate
Browse files Browse the repository at this point in the history
Generate getter fn for command arguments
  • Loading branch information
jontze authored Dec 8, 2023
2 parents 395d0e0 + 416d53a commit c12167c
Show file tree
Hide file tree
Showing 12 changed files with 298 additions and 284 deletions.
87 changes: 86 additions & 1 deletion cadency_codegen/src/argument.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
pub struct Argument {
use proc_macro2::Ident;
use syn::spanned::Spanned;

pub(crate) struct Argument {
pub name: String,
pub description: String,
pub kind: String,
Expand All @@ -15,7 +18,89 @@ impl Argument {
}
}

fn arg_name(&self) -> String {
self.name.trim().to_lowercase()
}

fn kind_token(&self) -> proc_macro2::TokenStream {
self.kind.parse().unwrap()
}

fn kind_ident(&self) -> Ident {
Ident::new(&self.kind, self.name.span())
}

fn rust_type(&self) -> proc_macro2::TokenStream {
match self.kind.as_str() {
"Boolean" => quote! { bool },
"Integer" => quote! { i64 },
"Number" => quote! { f64 },
"String" => quote! { String },
"SubCommand" | "SubCommandGroup" => {
quote! { Vec<serenity::model::application::CommandDataOption> }
}
"Attachment" => quote! { serenity::model::id::AttachmentId },
"Channel" => quote! { serenity::model::id::ChannelId },
"Mentionable" => quote! { serenity::model::id::GenericId },
"Role" => quote! { serenity::model::id::RoleId },
"User" => quote! { serenity::model::id::UserId },
"Unknown" => quote! { u8 },
_ => panic!("Unknown argument kind: {}", self.kind),
}
}

pub fn is_optional(&mut self) {
self.required = false;
}

pub fn to_cadency_command_option(&self) -> proc_macro2::TokenStream {
let name = self.arg_name();
let description = &self.description;
let kind_token = self.kind_token();
let required = self.required;
quote! {
__CadencyCommandOption {
name: #name,
description: #description,
kind: __CommandOptionType::#kind_token,
required: #required
}
}
}

pub fn to_getter_fn(&self) -> proc_macro2::TokenStream {
let arg_kind_ident = self.kind_ident();
let arg_rust_type = self.rust_type();

let arg_name = &self.name;
let fn_name_ident = Ident::new(&format!("arg_{arg_name}"), self.name.span());

let (fn_return_type, value_unwrap) = if self.required {
(quote! { #arg_rust_type }, quote! {.unwrap()})
} else {
(quote! { Option<#arg_rust_type> }, quote! {})
};

// Create a function to extract the argument from the command
quote! {
fn #fn_name_ident(
&self,
command: &serenity::model::application::CommandInteraction
) -> #fn_return_type {
command
.data
.options
.iter()
.find(|option| option.name == #arg_name)
.map(|option| option.value.to_owned())
.map(|value| {
match value {
serenity::model::application::CommandDataOptionValue::#arg_kind_ident(value) => value,
_ => unreachable!("Incorrect Type"),
}
})
#value_unwrap
}
}
}
}
2 changes: 1 addition & 1 deletion cadency_codegen/src/command.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::argument::Argument;

pub struct Command {
pub(crate) struct Command {
pub name: String,
pub description: String,
pub deferred: bool,
Expand Down
Loading

0 comments on commit c12167c

Please sign in to comment.