1use std::collections::HashMap;
2
3mod commands;
4mod components;
5mod events;
6mod slash_commands;
7
8pub use commands::*;
9pub use components::*;
10pub use events::*;
11pub use slash_commands::*;
12
13use crate::handlers::events::Event;
14use crate::models::channel::Channel;
15use crate::models::deleted_message_response::DeletedMessage;
16use crate::models::interaction::{Interaction, InteractionData};
17use crate::models::misc::Reconnect;
18use crate::models::reaction_response::Reaction;
19use crate::prelude::*;
20use crate::utils::*;
21use futures_util::FutureExt;
22
23use thiserror::Error;
24
25pub type HandlerFn = fn(
26 Message,
27 Vec<Value>,
28) -> std::pin::Pin<
29 Box<dyn futures_util::Future<Output = DescordResult> + Send + 'static>,
30>;
31
32#[derive(Error, Debug)]
33pub enum DescordError {
34 #[error("Missing required argument for command: {0}")]
35 MissingRequiredArgument(String),
36}
37
38#[macro_export]
39macro_rules! implemented_enum {
40 [ $vis:vis enum $name:ident { $($variant:ident),* $(,)? } ] => {
41 #[derive(Debug, Clone)]
42 $vis enum $name {
43 $($variant($variant),)*
44 }
45
46 $(
47 impl From<$variant> for $name {
48 fn from(value: $variant) -> Self {
49 $name::$variant(value)
50 }
51 }
52 )*
53 };
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
58pub enum ParamType {
59 String,
60 Int,
61 Bool,
62 Channel,
63 User,
64 Args,
65}
66
67#[derive(Debug, Clone)]
68pub enum Value {
69 String(String),
70 Int(isize),
71 Bool(bool),
72 Channel(Channel),
73 User(User),
74 Args(Vec<String>),
75
76 StringOption(Option<String>),
77 IntOption(Option<isize>),
78 BoolOption(Option<bool>),
79 ChannelOption(Option<Channel>),
80 UserOption(Option<User>),
81
82 None,
83}
84
85fn parse_args(input: &str) -> Vec<String> {
86 let mut args = Vec::new();
87 let mut current_arg = String::new();
88 let mut quote_char = None;
89 let mut chars = input.chars();
90
91 while let Some(c) = chars.next() {
92 match c {
93 ' ' | '\t' if quote_char.is_none() => {
94 if !current_arg.is_empty() {
95 args.push(current_arg.clone());
96 current_arg.clear();
97 }
98 }
99 '\'' | '"' => {
100 if quote_char.is_none() {
101 quote_char = Some(c);
102 current_arg.push(c);
103 } else if quote_char.unwrap() == c {
104 quote_char = None;
105 current_arg.remove(0);
106 } else {
107 current_arg.push(c);
108 }
109 }
110 _ => current_arg.push(c),
111 }
112 }
113
114 if !current_arg.is_empty() {
115 if quote_char.is_some() {
116 args.extend(current_arg.split_whitespace().map(|s| s.to_string()));
117 } else {
118 args.push(current_arg);
119 }
120 }
121
122 args
123}