1use crate::core::structs::bot_structs::{Bot, Bots, PublicBot};
2use crate::core::Cache;
3use crate::core::TokenBucket;
4
5use reqwest::{Client as ReqwestClient};
6use reqwest::header::{HeaderMap, HeaderValue};
7use serde::{Serialize, Deserialize};
8use tokio::time;
9
10use std::time::Duration;
11use std::sync::{Arc, Mutex};
12
13#[derive(Debug, Clone)]
14pub struct BotClient{
15 auth: String,
16 cache: Cache,
17 url: String,
18 bucket: Arc<Mutex<TokenBucket>>,
19 bot: String,
20 json: String,
21 data: Data,
22}
23
24#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
25pub(crate) enum Data {
26 Bot(),
27 PublicBots(),
28 Bots(),
29 String(),
30}
31
32#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
33pub enum BotResult {
34 Bot(Bot),
35 PublicBot(PublicBot),
36 Bots(Bots),
37 String(String),
38}
39
40impl BotClient {
41
42 pub fn new(auth: String) -> BotClient {
43 BotClient {
44 auth,
45 cache: Cache::new(),
46 url: String::new(),
47 bucket: Arc::new(Mutex::new(TokenBucket::new(10))),
48 bot: String::new(),
49 json: String::new(),
50 data: Data::Bot(),
51 }
52 }
53
54 pub fn create_bot(&mut self, name: &str) -> &mut Self {
56 self.url = "https://api.revolt.chat/bots/create".to_string();
57 self.json = format!("{{\"name\":\"{}\"}}", name);
58 self
59 }
60
61 pub fn fetch_public_bot(&mut self, target: &str) -> &mut Self {
63 self.data = Data::PublicBots();
64 self.url = format!("https://api.revolt.chat/bots/{}/invite", target);
65 self.bot = target.to_string();
66 self
67 }
68
69 pub fn invite_bot(&mut self, target: &str, server: &str) -> &mut Self {
73 self.url = format!("https://api.revolt.chat/bots/{}/invite", target);
74 self.json = format!("{{\"group\":\"{}\"}}", server);
75 self
76 }
77
78 pub fn fetch_owned_bot(&mut self, target: &str) -> &mut Self {
82 self.data = Data::Bot();
83 self.url = format!("https://api.revolt.chat/bots/{}", target);
84 self.bot = target.to_string();
85 self
86 }
87
88 pub fn fetch_owned_bots(&mut self) -> &mut Self {
90 self.data = Data::Bots();
91 self.url = "https://api.revolt.chat/bots/@me".to_string();
92 self
93 }
94
95 pub fn delete_bot(&mut self, target: &str) -> &mut Self {
97 self.url = format!("https://api.revolt.chat/bots/{}", target);
98 self
99 }
100
101 #[cfg(feature="experimental")]
103 pub fn edit_bot(&mut self, target: &str, changes: &str) -> &mut Self {
104 self.url = format!("https://api.revolt.chat/bots/{}", target);
105 self.json = changes.to_string();
106 self
107 }
108
109 #[tokio::main]
110 pub async fn get(&mut self) -> BotResult {
111
112 if self.cache.get(&self.bot).is_some() {
113 let text = self.cache.get(&self.bot).unwrap();
114 match text.1.to_lowercase().as_str(){
115 "bot" => {
116 if self.data == Data::Bot() {
117 let parsed_value: Bot = serde_json::from_str(&text.0).unwrap();
118 return BotResult::Bot(parsed_value);
119 }
120 },
121 "publicbot" => {
122 if self.data == Data::PublicBots() {
123 let parsed_value: PublicBot = serde_json::from_str(&text.0)
124 .expect(&format!("The bot you are searching for {} is not listed as public or the id is inccorect!", self.bot));
125 return BotResult::PublicBot(parsed_value);
126 }
127 },
128 _ => {
129 panic!("Error retriving item from cache")
130 }
131 }
132
133 }
134
135 let bucket = self.bucket.clone();
136 let mut bucket = bucket.lock().unwrap();
137
138 let mut header: HeaderMap = HeaderMap::new();
139 header.insert("x-session-token", HeaderValue::from_str(&self.auth).unwrap());
140
141 while !bucket.try_acquire() {
142 time::sleep(Duration::from_millis(100)).await;
143 }
144
145 let client = ReqwestClient::new().get(&self.url).headers(header).send().await.unwrap();
146
147 let body = client.text().await.unwrap();
149
150 return self.return_data(body)
151 }
152
153 fn return_data(&mut self, body: String) -> BotResult{
154 match self.data{
155 Data::Bot() => {
156 let value: Bot = serde_json::from_str(&body).unwrap();
157 self.cache.add(self.bot.clone(), (body, "Bot".to_string()));
158 return BotResult::Bot(value);
159 },
160 Data::PublicBots() => {
161 let value: PublicBot = serde_json::from_str(&body)
162 .expect(&format!("The bot you are searching for {} is not listed as public or the id is inccorect!", self.bot));
163 self.cache.add(self.bot.clone(), (body, "PublicBot".to_string()));
164 return BotResult::PublicBot(value);
165 },
166 Data::Bots() => {
167 let value: Bots = serde_json::from_str(&body).unwrap();
168 return BotResult::Bots(value);
169 }
170 _ => return BotResult::String(body)
171 }
172 }
173}