1 #![feature(proc_macro_hygiene)]
2
3 #[macro_use] extern crate rocket;
4 #[macro_use] extern crate rocket_contrib;
5 #[macro_use] extern crate serde_derive;
6
7 #[cfg(test)] mod tests;
8
9 use std::sync::Mutex;
10 use std::collections::HashMap;
11
12 use rocket::State;
13 use rocket_contrib::json::{Json, JsonValue};
14
15 // The type to represent the ID of a message.
16 type ID = usize;
17
18 // We're going to store all of the messages here. No need for a DB.
19 type MessageMap = Mutex<HashMap<ID, String>>;
20
21 #[derive(Serialize, Deserialize)]
22 struct Message {
23 id: Option<ID>,
24 contents: String
25 }
26
27 // TODO: This example can be improved by using `route` with multiple HTTP verbs.
28 #[post("/<id>", format = "json", data = "<message>")]
new(id: ID, message: Json<Message>, map: State<'_, MessageMap>) -> JsonValue29 fn new(id: ID, message: Json<Message>, map: State<'_, MessageMap>) -> JsonValue {
30 let mut hashmap = map.lock().expect("map lock.");
31 if hashmap.contains_key(&id) {
32 json!({
33 "status": "error",
34 "reason": "ID exists. Try put."
35 })
36 } else {
37 hashmap.insert(id, message.0.contents);
38 json!({ "status": "ok" })
39 }
40 }
41
42 #[put("/<id>", format = "json", data = "<message>")]
update(id: ID, message: Json<Message>, map: State<'_, MessageMap>) -> Option<JsonValue>43 fn update(id: ID, message: Json<Message>, map: State<'_, MessageMap>) -> Option<JsonValue> {
44 let mut hashmap = map.lock().unwrap();
45 if hashmap.contains_key(&id) {
46 hashmap.insert(id, message.0.contents);
47 Some(json!({ "status": "ok" }))
48 } else {
49 None
50 }
51 }
52
53 #[get("/<id>", format = "json")]
get(id: ID, map: State<'_, MessageMap>) -> Option<Json<Message>>54 fn get(id: ID, map: State<'_, MessageMap>) -> Option<Json<Message>> {
55 let hashmap = map.lock().unwrap();
56 hashmap.get(&id).map(|contents| {
57 Json(Message {
58 id: Some(id),
59 contents: contents.clone()
60 })
61 })
62 }
63
64 #[catch(404)]
not_found() -> JsonValue65 fn not_found() -> JsonValue {
66 json!({
67 "status": "error",
68 "reason": "Resource was not found."
69 })
70 }
71
rocket() -> rocket::Rocket72 fn rocket() -> rocket::Rocket {
73 rocket::ignite()
74 .mount("/message", routes![new, update, get])
75 .register(catchers![not_found])
76 .manage(Mutex::new(HashMap::<ID, String>::new()))
77 }
78
main()79 fn main() {
80 rocket().launch();
81 }
82