Rocket/examples/json/src/main.rs

82 lines
2.0 KiB
Rust

#![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<HashMap<ID, String>>;
#[derive(Serialize, Deserialize)]
struct Message {
id: Option<ID>,
contents: String
}
// TODO: This example can be improved by using `route` with multiple HTTP verbs.
#[post("/<id>", format = "json", data = "<message>")]
fn new(id: ID, message: Json<Message>, 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("/<id>", format = "json", data = "<message>")]
fn update(id: ID, message: Json<Message>, map: State<'_, MessageMap>) -> Option<JsonValue> {
let mut hashmap = map.lock().unwrap();
if hashmap.contains_key(&id) {
hashmap.insert(id, message.0.contents);
Some(json!({ "status": "ok" }))
} else {
None
}
}
#[get("/<id>", format = "json")]
fn get(id: ID, map: State<'_, MessageMap>) -> Option<Json<Message>> {
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::<ID, String>::new()))
}
fn main() {
rocket().launch();
}