Skip to content

Commit

Permalink
Merge pull request #1 from pepoviola/refactor-create-rest-entity-struct
Browse files Browse the repository at this point in the history
refactor - rest entity
  • Loading branch information
pepoviola authored Oct 3, 2020
2 parents b6be779 + 255387e commit dc8eca2
Showing 1 changed file with 83 additions and 60 deletions.
143 changes: 83 additions & 60 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,71 @@ struct Dinos {
dinos: Vec<Dino>,
}

struct RestEntity {
base_path: String,
}

impl RestEntity {
async fn create(mut req: Request<State>) -> tide::Result {
let dino: Dino = req.body_json().await?;
// let get a mut ref of our store ( hashMap )
let mut dinos = req.state().dinos.write().await;
dinos.insert(String::from(&dino.name), dino.clone());
let mut res = Response::new(201);
res.set_body(Body::from_json(&dino)?);
Ok(res)
}

async fn list(req: tide::Request<State>) -> tide::Result {
let dinos = req.state().dinos.read().await;
// get all the dinos as a vector
let dinos_vec: Vec<Dino> = dinos.values().cloned().collect();
let mut res = Response::new(200);
res.set_body(Body::from_json(&dinos_vec)?);
Ok(res)
}

async fn get(req: tide::Request<State>) -> tide::Result {
let mut dinos = req.state().dinos.write().await;
let key: String = req.param("id")?;
let res = match dinos.entry(key) {
Entry::Vacant(_entry) => Response::new(404),
Entry::Occupied(entry) => {
let mut res = Response::new(200);
res.set_body(Body::from_json(&entry.get())?);
res
}
};
Ok(res)
}

async fn update(mut req: tide::Request<State>) -> tide::Result {
let dino_update: Dino = req.body_json().await?;
let mut dinos = req.state().dinos.write().await;
let key: String = req.param("id")?;
let res = match dinos.entry(key) {
Entry::Vacant(_entry) => Response::new(404),
Entry::Occupied(mut entry) => {
*entry.get_mut() = dino_update;
let mut res = Response::new(200);
res.set_body(Body::from_json(&entry.get())?);
res
}
};
Ok(res)
}

async fn delete(req: tide::Request<State>) -> tide::Result {
let mut dinos = req.state().dinos.write().await;
let key: String = req.param("id")?;
let deleted = dinos.remove(&key);
let res = match deleted {
None => Response::new(404),
Some(_) => Response::new(204),
};
Ok(res)
}
}
#[async_std::main]
async fn main() {
tide::log::start();
Expand All @@ -30,6 +95,17 @@ async fn main() {
app.listen("127.0.0.1:8080").await.unwrap();
}

fn register_rest_entity(app: &mut Server<State>, entity: RestEntity) {
app.at(&entity.base_path)
.get(RestEntity::list)
.post(RestEntity::create);

app.at(&format!("{}/:id", entity.base_path))
.get(RestEntity::get)
.put(RestEntity::update)
.delete(RestEntity::delete);
}

async fn server(dinos_store: Arc<RwLock<HashMap<String, Dino>>>) -> Server<State> {
let state = State {
dinos: dinos_store, //Default::default(),
Expand All @@ -38,76 +114,23 @@ async fn server(dinos_store: Arc<RwLock<HashMap<String, Dino>>>) -> Server<State
let mut app = tide::with_state(state);
app.at("/").get(|_| async { Ok("ok") });

app.at("/dinos")
.post(|mut req: Request<State>| async move {
let dino: Dino = req.body_json().await?;
// let get a mut ref of our store ( hashMap )
let mut dinos = req.state().dinos.write().await;
dinos.insert(String::from(&dino.name), dino.clone());
println!("{:?}", dinos);
let mut res = Response::new(201);
res.set_body(Body::from_json(&dino)?);
Ok(res)
})
.get(|req: Request<State>| async move {
let dinos = req.state().dinos.read().await;
// get all the dinos as a vector
let dinos_vec: Vec<Dino> = dinos.values().cloned().collect();
let mut res = Response::new(200);
res.set_body(Body::from_json(&dinos_vec)?);
Ok(res)
});
app.at("/dinos/:name")
.get(|req: Request<State>| async move {
let mut dinos = req.state().dinos.write().await;
let key: String = req.param("name")?;
let res = match dinos.entry(key) {
Entry::Vacant(_entry) => Response::new(404),
Entry::Occupied(entry) => {
let mut res = Response::new(200);
res.set_body(Body::from_json(&entry.get())?);
res
}
};
Ok(res)
})
.put(|mut req: Request<State>| async move {
let dino_update: Dino = req.body_json().await?;
let mut dinos = req.state().dinos.write().await;
let key: String = req.param("name")?;
let res = match dinos.entry(key) {
Entry::Vacant(_entry) => Response::new(404),
Entry::Occupied(mut entry) => {
*entry.get_mut() = dino_update;
let mut res = Response::new(200);
res.set_body(Body::from_json(&entry.get())?);
res
}
};
Ok(res)
})
.delete(|req: Request<State>| async move {
let mut dinos = req.state().dinos.write().await;
let key: String = req.param("name")?;
let deleted = dinos.remove(&key);
let res = match deleted {
None => Response::new(404),
Some(_) => Response::new(204),
};
Ok(res)
});
let dinos_endpoint = RestEntity {
base_path: String::from("/dinos"),
};

register_rest_entity(&mut app, dinos_endpoint);

app
}

#[async_std::test]
async fn index_page() -> tide::Result<()> {
use tide::http::{Method, Request, Response, Url};
use tide::http::{Method, Request as httpRequest, Response, Url};

let dinos_store = Default::default();
let app = server(dinos_store).await;
let url = Url::parse("https://example.com").unwrap();
let req = Request::new(Method::Get, url);
let req = httpRequest::new(Method::Get, url);
let mut res: Response = app.respond(req).await?;
assert_eq!("ok", res.body_string().await?);
Ok(())
Expand Down

0 comments on commit dc8eca2

Please sign in to comment.