Advertisement
aircampro

rust webserver on tide and async-std

Nov 11th, 2023 (edited)
4,994
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 6.99 KB | Source Code | 0 0
  1. // webserver on rust using tide async-std and serde
  2. //
  3. // [dependencies]
  4. // tide = "0.16.0"
  5. // async-std = { version = "1.6.0", features = ["attributes"] }
  6. // serde = { version = "1.0", features = ["derive"]
  7. //
  8. use tide::Request;
  9. //use tide::Response;
  10. //use tide::Result;
  11. //use tide::StatusCode;
  12. use tide::prelude::*;
  13. use serde::{Deserialize, Serialize};
  14. use std::collections::HashMap;
  15. use std::collections::hash_map::{Entry};
  16. use std::sync::{Arc, RwLock};
  17.  
  18. #[derive(Serialize, Deserialize)]
  19. struct Animal {
  20.         name: String,
  21.         age: u8,
  22. }
  23. #[derive(Hash, Eq, PartialEq, Clone, Debug, Deserialize, Serialize)]
  24. struct Dino {
  25.         name: String,
  26.         weight: u16,
  27.         diet: String
  28. }
  29. #[derive(Clone, Debug, Deserialize, Serialize)]
  30. struct State {
  31.         dinos: Arc<RwLock<HashMap<String, Dino>>>
  32. }
  33. #[derive(Debug, Deserialize)]
  34. struct QueryObj {
  35.     id: String,
  36.     name: String,
  37. }
  38. #[derive(Debug, Deserialize, Serialize)]
  39. struct Counter {
  40.     count: usize,
  41. }
  42. #[derive(Debug, Deserialize)]
  43. struct Order {
  44.     name: String,
  45.     shoes: u16,
  46. }
  47.    
  48. #[async_std::main]
  49. async fn main() -> Result<(), std::io::Error> {
  50. //async fn main() -> Result<()> {
  51.         tide::log::start();
  52.         let state = State {
  53.             dinos: Default::default()
  54.         };
  55.         //let mut app = tide::new();          
  56.         let mut app = tide::with_state(state);
  57.         // curl -i 'localhost:8080'
  58.         // server replies with hello world
  59.         //
  60.         app.at("/").get(|_| async { Ok("Hello, world!") });
  61.         // curl -i -H "Acceptication/json" -d '{ "count": 41 }' -X GET localhost:8080/counter
  62.         // returns HTML with the count supplied incremented by 1 unit
  63.         //
  64.         app.at("/counter").get(|mut req: tide::Request<State>| async move {
  65.             let mut counter: Counter = req.body_json().await.unwrap();
  66.             println!("count is {}", counter.count);
  67.             counter.count += 1;
  68.             //tide::Response::new(200).body_json(&counter).unwrap()
  69.             Ok(tide::Response::builder(200)
  70.                  .body(format!("<html><h2>New Count is :-, {}!</h2></html>",
  71.                   counter.count))
  72.                  .header("Server", "tide")
  73.                  .content_type(tide::http::mime::HTML)
  74.                  .build())
  75.         });
  76.         // curl -i 'localhost:8080/nicko'
  77.         // returns the htm using the variable as nicko in the example
  78.         //
  79.         app.at("/:user").get(|req: tide::Request<State>| async move {
  80.             Ok(tide::Response::builder(200)
  81.                  .body(format!("<html><h2>Hello, {}!</h2></html>",
  82.                   req.param("user")?))
  83.                  .header("Server", "tide")
  84.                  .content_type(tide::http::mime::HTML)
  85.                  .build())
  86.         });
  87.         // curl -i 'localhost:8080/index'
  88.         // returns the html page index.html
  89.         //        
  90.         app.at("/index").serve_file("index.html")?;
  91.         // curl -i 'localhost:8080/animals'
  92.         // returns the hardcoded json as below
  93.         //
  94.         app.at("/animals").get(|_| async {
  95.             let animals = vec![
  96.                 Animal { name: "nick".into(), age: 8 },
  97.                 Animal { name: "paul".into(),   age: 3 },
  98.             ];
  99.             Ok(tide::Body::from_json(&animals)?)
  100.         });
  101.         // curl -X POST -H "Content-Type: application/json" -d '{"name":"nick","age":19}' localhost:8080/animal
  102.         // returns the animal names sent as a json message
  103.         //
  104.         app.at("/animal").post(|mut req: tide::Request<State>| async move {
  105.             let animal: Animal = req.body_json().await?;
  106.             Ok(tide::Body::from_json(&animal)?)
  107.         });
  108.         //  curl -d '{"name":"dinodino", "weight": 50, "diet":"carnivorous"}' http://localhost:8080/dinos
  109.         //  returns the json sent as a json message
  110.         //
  111.         app.at("/dinos").post(|mut req: tide::Request<State>| async move {
  112.             let dino: Dino = req.body_json().await?;
  113.             println!("{:?}", dino);
  114.             let mut dinos  = req.state().dinos.write();
  115.             let mut hash_dino: HashMap<String, Dino> = HashMap::new();
  116.             hash_dino.insert(String::from(&dino.name), dino.clone());
  117.             let dinos = hash_dino;
  118.             let mut res = tide::Response::new(201);
  119.             res.set_body(tide::Body::from_json(&dino)?);
  120.             Ok(res)
  121.         });
  122.         // curl --dump-header - localhost:8080/hashmapsearch/<name> e.g. <name>=mark
  123.         // responds with the number associated with the name specified as <name>
  124.         //
  125.         app.at("/hashmapsearch/:name")
  126.             .get(|req: Request<State>| async move {
  127.               let key: String = req.param("name").unwrap().to_string();
  128.               let mut hash_map: HashMap<String, i32> = HashMap::new();
  129.               hash_map.insert(String::from("mark"), 82);
  130.               hash_map.insert(String::from("nicholas"), 76);
  131.               hash_map.insert(String::from("anton"), 67);
  132.               hash_map.insert(String::from("ellis"), 2);
  133.               hash_map.insert(String::from("dee"), 11);
  134.               hash_map.insert(String::from("eamon"), 99);
  135.               hash_map.insert(String::from("jock"), 14);
  136.               hash_map.insert(String::from("iain"), 83);
  137.               let res = match hash_map.entry(key) {                              
  138.                  Entry::Vacant(_entry) => tide::Response::new(404),
  139.                  Entry::Occupied(entry) => {
  140.                  let mut res = tide::Response::new(200);
  141.                  res.set_body(tide::Body::from_json(&entry.get())?);
  142.                  res
  143.               }
  144.            };
  145.            Ok(res)
  146.         });
  147.         // curl -i 'localhost:8080/users?id=1&name=mark'
  148.         // returns the name and id sent as a html page message
  149.         //
  150.         app.at("/users").get(|req: Request<State>| {
  151.             async move {
  152.                 let user_id = req.query::<QueryObj>().unwrap();
  153.                 Ok(tide::Response::builder(200)
  154.                  .body(format!("<html><h2>Hello, {} your id was {}!</h2></html>",
  155.                   user_id.name, user_id.id))
  156.                  .header("Server", "tide")
  157.                  .content_type(tide::http::mime::HTML)
  158.                  .build())
  159.             }
  160.         });
  161.         // curl --dump-header - localhost:8080/hc
  162.         // curl --dump-header - localhost:8080/hc/json
  163.         // prints the parsed route back to the client
  164.         //    
  165.         app.at("/hc")
  166.            .get(|_| async move { Ok("ok hc!") })
  167.            .at("/json")
  168.            .get(|_| async move { Ok("ok json!") });
  169.         // curl localhost:8080/orders/shoes -d '{ "name": "Thom", "shoes": 4 }'
  170.         //
  171.         app.at("/orders/shoes").post(order_shoes);          
  172.         app.listen("127.0.0.1:8080").await?;
  173.         Ok(())
  174. }
  175.  
  176. async fn order_shoes(mut req: Request<State>) -> tide::Result {
  177.     let Order { name, shoes } = req.body_json().await?;
  178.     Ok(format!("Hello, {}! I've put in an order for {} shoes", name, shoes).into())
  179. }
Tags: #rust #tide
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement