diff --git a/src/app/robots.rs b/src/app/robots.rs index ec513ff..e41cfe8 100644 --- a/src/app/robots.rs +++ b/src/app/robots.rs @@ -10,16 +10,14 @@ use crate::simple::HandlingError; #[derive(Serialize, Deserialize)] pub struct GetRobot { #[serde(skip_deserializing)] - pub id: i64, + pub id: Option, pub name: String, } -type Model = GetRobot; - impl std::convert::From for GetRobot { fn from(r: robots::Robot) -> GetRobot { GetRobot { - id: r.id, + id: Some(r.id), name: r.name, } } @@ -72,14 +70,14 @@ pub async fn get_all( pool: PgSharedPool, offset: i64, limit: i64, -) -> Result<(Vec, bool), HandlingError> { +) -> Result<(Vec, bool), HandlingError> { let mut tx = pool .begin() .await .map(|c| Box::new(c)) .map_err(|e| HandlingError::DBError(e))?; - let mut repo = postgres::ModelImpl::new(&mut tx); + let mut repo = postgres::RobotsImpl::new(&mut tx); let (items, next) = repo.get_all()?.paginate(offset, limit).await?; let data = items.into_iter().map(|r| r.into()).collect(); @@ -114,7 +112,7 @@ pub async fn delete_robot(pool: PgSharedPool, id: i64) -> Result<(), HandlingErr .map(|c| Box::new(c)) .map_err(|e| HandlingError::DBError(e))?; - let mut repo = postgres::ModelImpl::new(&mut tx); + let mut repo = postgres::RobotsImpl::new(&mut tx); let _: () = robots::delete(&mut repo, id).await?; tx.commit().await.map_err(|e| HandlingError::DBError(e))?; diff --git a/src/data/postgres.rs b/src/data/postgres.rs index 220fa26..e605681 100644 --- a/src/data/postgres.rs +++ b/src/data/postgres.rs @@ -14,6 +14,7 @@ pub struct Collection<'a> { } impl Collection<'_> { + #[allow(dead_code)] pub fn by_id(self, id: i64) -> Self { Self { tx: self.tx, @@ -62,8 +63,6 @@ pub struct RobotsImpl<'a> { pub tx: &'a mut Box>, } -pub type ModelImpl<'a> = RobotsImpl<'a>; - impl<'a> RobotsImpl<'_> { pub fn new<'b>(tx: &'b mut Box>) -> RobotsImpl<'b> { RobotsImpl { tx: tx } diff --git a/src/http/robots.rs b/src/http/robots.rs index 1bf7ae0..883f63f 100644 --- a/src/http/robots.rs +++ b/src/http/robots.rs @@ -21,6 +21,7 @@ struct Pagination { pub next: bool, } +// add a new robot entry async fn create( pool: PgSharedPool, r: app::robots::GetRobot, @@ -28,10 +29,12 @@ async fn create( reply_json(app::robots::add_robot(pool, r).await) } +// retrieve information of a single robot async fn get(pool: PgSharedPool, id: i64) -> Result { reply_json(app::robots::get_robot(pool, id).await) } +// updates robot information async fn update( pool: PgSharedPool, id: i64, @@ -40,6 +43,7 @@ async fn update( reply_json(app::robots::update_robot(pool, id, r).await) } +// returns a pagination of all robots async fn get_all( pool: PgSharedPool, p: PaginationOptions, @@ -54,6 +58,7 @@ async fn get_all( ) } +// will delete the requested robot async fn delete(pool: PgSharedPool, id: i64) -> Result { match app::robots::delete_robot(pool, id).await { Ok(_) => Ok(warp::reply::with_status( @@ -64,45 +69,81 @@ async fn delete(pool: PgSharedPool, id: i64) -> Result, pool: PgSharedPool, ) -> warp::filters::BoxedFilter<(impl warp::Reply,)> { + // create a prefix that injects a database connection for every request + // every filter is added after the prefix so it receives a database connection let prefix = warp::path!("robots").map(move || pool.clone()); - base.or(prefix - .clone() - .and(warp::filters::method::post()) - .and(warp::body::json()) - .and_then(create)) - .or(prefix + base.or( + // filter for creating new robots + prefix .clone() + // match HTTP POST method + .and(warp::filters::method::post()) + // attempts to parse the request's body as JSON + .and(warp::body::json()) + // bind the handler + .and_then(create), + ) + .or( + // filter for retrieving a pagination of robots + prefix + .clone() + // match HTTP GET method .and(warp::filters::method::get()) + // add pagination query parameters .and(warp::filters::query::query()) - .and_then(get_all)) - .boxed() + // bind the handler + .and_then(get_all), + ) + .boxed() } +// build the route structure for the "/robot/{id}" endpoint pub fn with_id( base: warp::filters::BoxedFilter<(impl warp::Reply + 'static,)>, pool: PgSharedPool, ) -> warp::filters::BoxedFilter<(impl warp::Reply,)> { + // we create a prefix containing the id of a robot and a shared database connection + // every filter is added after the prefix + // so it receives a robot's id and a database connection let prefix = warp::path!("robot" / i64) .map(move |id| (pool.clone(), id)) .untuple_one(); - base.or(prefix - .clone() - .and(warp::filters::method::get()) - .and_then(get)) - .or(prefix + // append the routes to the base filter + base.or( + // filter to get information on a robot + prefix .clone() + // match HTTP GET method + .and(warp::filters::method::get()) + // bind the handler + .and_then(get), + ) + .or( + // filter for updating individual robots + prefix + .clone() + // metch HTTP POST method .and(warp::filters::method::put()) + // attempts to parse the request's body as JSON .and(warp::body::json()) - .and_then(update)) - .or(prefix + // bind the handler + .and_then(update), + ) + .or( + // filter that deletes a robot entry + prefix .clone() + // match HTTP DELETE method .and(warp::filters::method::delete()) - .and_then(delete)) - .boxed() + // bind the handler + .and_then(delete), + ) + .boxed() }