#![feature(plugin)] #![plugin(rocket_codegen)] extern crate rocket; extern crate serde_json; #[macro_use] extern crate rocket_contrib; #[macro_use] extern crate serde_derive; #[cfg(test)] mod tests; use rocket_contrib::{JSON, Value}; use rocket::State; use std::collections::HashMap; use std::sync::Mutex; // 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 muliple HTTP verbs. #[post("/", format = "application/json", data = "")] fn new(id: ID, message: JSON, map: State) -> JSON { let mut hashmap = map.lock().expect("map lock."); if hashmap.contains_key(&id) { JSON(json!({ "status": "error", "reason": "ID exists. Try put." })) } else { hashmap.insert(id, message.0.contents); JSON(json!({ "status": "ok" })) } } #[put("/", format = "application/json", data = "")] fn update(id: ID, message: JSON, map: State) -> Option> { let mut hashmap = map.lock().unwrap(); if hashmap.contains_key(&id) { hashmap.insert(id, message.0.contents); Some(JSON(json!({ "status": "ok" }))) } else { None } } #[get("/", format = "application/json")] fn get(id: ID, map: State) -> Option> { let hashmap = map.lock().unwrap(); hashmap.get(&id).map(|contents| { JSON(Message { id: Some(id), contents: contents.clone() }) }) } #[error(404)] fn not_found() -> JSON { JSON(json!({ "status": "error", "reason": "Resource was not found." })) } fn rocket() -> rocket::Rocket { rocket::ignite() .mount("/message", routes![new, update, get]) .catch(errors![not_found]) .manage(Mutex::new(HashMap::::new())) } fn main() { rocket().launch(); }