#![feature(proc_macro_hygiene)] #[macro_use] extern crate rocket; #[macro_use] extern crate rocket_contrib; #[macro_use] extern crate serde_derive; #[cfg(test)] mod tests; use std::sync::Mutex; use std::collections::HashMap; use rocket::State; use rocket_contrib::json::{Json, JsonValue}; // The type to represent the ID of a message. type ID = usize; // We're going to store all of the messages here. No need for a DB. type MessageMap = Mutex>; #[derive(Serialize, Deserialize)] struct Message { id: Option, contents: String } // TODO: This example can be improved by using `route` with multiple HTTP verbs. #[post("/", format = "json", data = "")] fn new(id: ID, message: Json, map: State<'_, MessageMap>) -> JsonValue { let mut hashmap = map.lock().expect("map lock."); if hashmap.contains_key(&id) { json!({ "status": "error", "reason": "ID exists. Try put." }) } else { hashmap.insert(id, message.0.contents); json!({ "status": "ok" }) } } #[put("/", format = "json", data = "")] fn update(id: ID, message: Json, map: State<'_, MessageMap>) -> Option { let mut hashmap = map.lock().unwrap(); if hashmap.contains_key(&id) { hashmap.insert(id, message.0.contents); Some(json!({ "status": "ok" })) } else { None } } #[get("/", format = "json")] fn get(id: ID, map: State<'_, MessageMap>) -> Option> { let hashmap = map.lock().unwrap(); hashmap.get(&id).map(|contents| { Json(Message { id: Some(id), contents: contents.clone() }) }) } #[catch(404)] fn not_found() -> JsonValue { json!({ "status": "error", "reason": "Resource was not found." }) } fn rocket() -> rocket::Rocket { rocket::ignite() .mount("/message", routes![new, update, get]) .register(catchers![not_found]) .manage(Mutex::new(HashMap::::new())) } fn main() { rocket().launch(); }