#![feature(plugin)] #![plugin(rocket_codegen)] extern crate rocket; extern crate serde_json; #[macro_use] extern crate lazy_static; #[macro_use] extern crate rocket_contrib; #[macro_use] extern crate serde_derive; #[cfg(test)] mod tests; use rocket_contrib::{JSON, Value}; 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. lazy_static! { static ref MAP: Mutex> = Mutex::new(HashMap::new()); } #[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) -> 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) -> 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) -> 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 main() { rocket::ignite() .mount("/message", routes![new, update, get]) .catch(errors![not_found]) .launch(); }