#[macro_use] extern crate rocket; use rocket::serde::json::Json; use std::collections::HashMap; use rocket::State; use std::sync::Mutex; use std::time::SystemTime; #[derive(serde::Serialize)] struct Response (Result); #[get("/get_message/")] fn get_message(id: usize, db: &State) -> Json> { let lock = db.sdb.lock().unwrap(); match lock.get_message(id) { Some(n) => Json(Response(Ok(n))), None => Json(Response(Err("Message not found"))), } } #[get("/get_message_id_list//")] fn get_message_id_list(id_start: usize, id_end: usize, db: &State) -> Json, &'static str>> { let lock = db.sdb.lock().unwrap(); let list = lock.get_message_id_list(id_start, id_end); if list.len() == 0 { Json(Response(Err("No messages"))) } else { Json(Response(Ok(list))) } } #[get("/get_message_id_newest")] fn get_message_id_newest(db: &State) -> Json> { let lock = db.sdb.lock().unwrap(); match lock.get_message_newest_id() { Some(n) => Json(Response(Ok(n))), None => Json(Response(Err("No messages"))) } } #[get("/send_message//")] fn send_message(user_id: usize, msg: String, db: &State) -> Json> { let mut lock = db.sdb.lock().unwrap(); let user = match lock.get_user(user_id) { Some(n) => n, None => return Json(Response(Err("User not found"))) }; let msg = Message::new(msg, user, lock.get_next_message_id(), None); lock.send_message(&msg); Json(Response(Ok(msg.id))) } #[get("/send_reply///")] fn send_reply(user_id: usize, message_id: usize, msg: String, db: &State) -> Json> { let mut lock = db.sdb.lock().unwrap(); let user = match lock.get_user(user_id) { Some(n) => n, None => return Json(Response(Err("User not found"))) }; let msg = Message::new(msg, user, lock.get_next_message_id(), Some(message_id)); lock.send_message(&msg); Json(Response(Ok(msg.id))) } #[get("/delete_message/")] fn delete_message(id: usize, db: &State) -> Json> { let mut lock = db.sdb.lock().unwrap(); Json(Response(lock.delete_message(id))) } #[get("/get_user/")] fn get_user(id: usize, db: &State) -> Json> { let lock = db.sdb.lock().unwrap(); match lock.get_user(id) { Some(n) => Json(Response(Ok(n))), None => Json(Response(Err("User not found"))) } } #[get("/get_user_by_name/")] fn get_user_by_name(name: String, db: &State) -> Json, &'static str>> { let lock = db.sdb.lock().unwrap(); match lock.get_user_by_name(name) { Some(n) => Json(Response(Ok(n))), None => Json(Response(Err("User not found"))) } } #[get("/create_user/")] fn create_user(name: String, db: &State) -> Json> { let mut lock = db.sdb.lock().unwrap(); Json(Response(lock.create_user(name))) } struct SharedDB { sdb: Mutex } struct Database { usermap: HashMap, messagemap: HashMap, } impl Database { fn get_message(&self, id: usize) -> Option { match self.messagemap.get(&id) { Some(n) => Some(n.to_owned()), None => None, } } fn get_message_id_list(&self, id_start: usize, id_end: usize) -> Vec { let mut message_id_vec: Vec = vec![]; for x in id_start..=id_end { match self.messagemap.get(&x) { Some(_) => message_id_vec.push(x), None => (), } } return message_id_vec; } fn get_next_message_id(&self) -> usize { self.messagemap.len() } fn get_message_newest_id(&self) -> Option { let newest = self.get_next_message_id() as isize - 1; let newest = if newest < 0 {0} else {newest as usize}; match self.messagemap.get(&newest) { Some(_) => Some(newest), None => None, } } fn send_message(&mut self, msg: &Message) { self.messagemap.insert(msg.id, msg.clone()); println!("{:?}", self.messagemap.get(&0)); } fn delete_message(&mut self, id: usize) -> Result<&'static str, &'static str> { let msg = match self.messagemap.get_mut(&id) { Some(n) => n, None => return Err("Message not found"), }; msg.delete(); Ok("Deleted") } fn get_user(&self, id: usize) -> Option { match self.usermap.get(&id) { Some(n) => Some(n.to_owned()), None => None } } fn get_user_by_name(&self, name: String) -> Option> { let list: Vec> = self.usermap.values().map(|x| if x.username == name {Some(x.clone())} else {None}).collect(); let mut users = vec![]; for x in list { match x { Some(n) => users.push(n), None => () } } if users.len() == 0 { None } else { Some(users) } } fn create_user(&mut self, name: String) -> Result { let id = self.usermap.len(); let user = User::new(name.clone(), id); match self.get_user_by_name(name) { Some(_) => return Err("ID taken"), None => (), } match self.usermap.get(&id) { Some(_) => Err("ID taken"), None => {self.usermap.insert(id, user.clone()); Ok(user)}, } } pub fn new() -> Database { Database { usermap: HashMap::new(), messagemap: HashMap::new(), } } } #[derive(serde::Serialize, Clone, Debug)] struct Date { date: u64, } impl Date { pub fn now() -> Date { Date{ date: SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() } } } #[derive(serde::Serialize, Clone, Debug)] struct User { username: String, id: usize } impl User { pub fn new(name: String, id: usize) -> User { User{ username: name, id: id } } } #[derive(serde::Serialize, Clone, Debug)] struct Message { date: Date, message: String, sender: User, id: usize, reply_to: Option, // Message ID deleted: bool, } impl Message { pub fn new(msg: String, sender: User, id: usize, reply_to: Option) -> Message { Message { date: Date::now(), sender: sender, message: msg, id: id, reply_to: reply_to, deleted: false, } } fn delete(&mut self) { self.message.clear(); self.deleted = true; } } #[derive(serde::Serialize)] struct Info { name: String, users: usize, } impl Info { pub fn get(db: std::sync::MutexGuard) -> Info { Info{ name: String::from("Testing"), users: db.usermap.len(), } } } #[get("/ping")] fn ping() -> Json> { Json(Response(Ok("pong"))) } #[get("/api")] fn api_index(db: &State) -> Json { let lock = db.sdb.lock().unwrap(); Json(Info::get(lock)) } #[derive(serde::Serialize)] struct HitCount { c: usize } #[launch] fn rocket() -> _ { rocket::build() .mount("/api", routes![ get_message, send_message, get_message_id_list, ping, get_user, create_user, get_user_by_name, get_message_id_newest, send_reply, delete_message, ]) .mount("/", routes![api_index]) .manage(SharedDB{sdb: Mutex::new(Database::new())}) }