diff --git a/api/Cargo.toml b/api/Cargo.toml index 7c4fe3b..6c526a4 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "packager-api" version = "0.1.0" -edition = "2018" +edition = "2021" [lib] name = "packager" diff --git a/api/README.md b/api/README.md new file mode 100644 index 0000000..1265a77 --- /dev/null +++ b/api/README.md @@ -0,0 +1,25 @@ +# Setup + +* Install `rustup` + +On Arch Linux: + +``` +$ sudo pacman -S rustup +``` + +``` +$ rustup toolchain install nightly +``` + +# Run Dev + +``` +$ rustup run nightly cargo run +``` + +# Build + +``` +$ rustup run nightly cargo build --release +``` diff --git a/api/src/lib.rs b/api/src/lib.rs index 85287a3..a830363 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -1,12 +1,14 @@ use uuid::Uuid; pub mod packagelist; -pub use packagelist::PackageList; pub use packagelist::PackageItem; -// use self::packagelist; +pub use packagelist::PackageList; pub mod router; -// pub use crate::packager::packagelist; + +pub mod trip; +pub use trip::Trip; +pub use trip::TripList; pub fn get_list(id: Uuid) -> Option { println!("Looking for id {}", id); @@ -21,6 +23,21 @@ pub fn get_list(id: Uuid) -> Option { None } +pub fn get_trips() -> Vec { + let package_lists = get_lists(); + vec![ + Trip::from_package_list( + Uuid::parse_str("98dd50f9-b945-48e0-8fa9-41a3fd8b897e").unwrap(), + String::from("Campingtrip"), + String::from("2021-09-06"), + vec![ + package_lists[0].id, + package_lists[1].id, + ], + ) + ] +} + pub fn get_lists() -> Vec { vec![ packagelist::PackageList::new_from_items( diff --git a/api/src/main.rs b/api/src/main.rs index 7e02912..051f77e 100644 --- a/api/src/main.rs +++ b/api/src/main.rs @@ -1,139 +1,38 @@ use packager; -use uuid::Uuid; - -#[derive(Debug)] -enum TripItemStatus { - Pending, - Ready, - Packed, -} - -#[derive(Debug)] -struct TripItem<'a> { - package_item: &'a packager::PackageItem, - status: TripItemStatus, -} - -impl TripItem<'_> { - fn from_package_item(package_item: &packager::PackageItem) -> TripItem { - TripItem { - package_item, - status: TripItemStatus::Pending, - } - } - - fn set_status(&mut self, status: TripItemStatus) { - self.status = status; - } -} - -#[derive(Debug)] -struct TripList<'a> { - items: Vec>, -} - -impl<'a> TripList<'a> { - fn from_package_list(list: &'a packager::PackageList) -> TripList<'a> { - let mut items = Vec::new(); - for item in &list.items { - items.push(TripItem::from_package_item(item)); - } - - TripList { items } - } -} - -#[derive(Debug)] -struct Trip<'a> { - name: String, - date: String, - list: TripList<'a>, -} - -impl<'a> Trip<'a> { - fn from_package_list(name: String, date: String, list: &'a packager::PackageList) -> Trip<'a> { - Trip { - name, - date, - list: TripList::from_package_list(list), - } - } -} - -// for list in &lists { -// println!("Contents of package list {:?}:", list.name); -// for item in &list.items { -// println!("\t{:?}", item); -// } -// } - -// println!("\nNow we're starting an actual trip!"); - -// let mut trip = Trip::from_package_list( -// String::from("Campingtrip"), -// String::from("2021-09-06"), -// &lists[0], -// ); - -// println!( -// "\nPackage list for trip {:?} at {:?}:", -// trip.name, trip.date -// ); -// for item in &trip.list.items { -// println!("{:?}", item); -// } - -// trip.list.items[0].set_status(TripItemStatus::Ready); -// trip.list.items[1].set_status(TripItemStatus::Packed); -// for item in &trip.list.items { -// println!("{:?}", item); -// } #[tokio::main] async fn main() { -// let accept_json = warp::header::exact("accept", "application/json"); -// let cors = warp::cors().allow_any_origin(); + // let lists = packager::get_lists(); -// let root = warp::path::end() -// .map(|| "Hi") -// .recover(packager::router::handle_rejection); + // for list in &lists { + // println!("Contents of package list {:?}:", list.name); + // for item in &list.items { + // println!("\t{:?}", item); + // } + // } -// let v1 = warp::path!("v1") -// .and(warp::get()) -// .and(warp::path::end()) -// .map(warp::reply) -// .recover(packager::router::handle_rejection); + // println!("\nNow we're starting an actual trip!"); -// let lists = warp::path!("v1" / "lists") -// .and(warp::path::end()) -// .and(warp::get()) -// .and(accept_json) -// .map(|| warp::reply::json(&packager::get_lists())) -// .with(&cors) -// .recover(packager::router::handle_rejection); + // let mut trip = packager::trip::Trip::from_package_list( + // String::from("Campingtrip"), + // String::from("2021-09-06"), + // &lists[0], + // ); -// let list = warp::path!("v1" / "lists" / String) -// .and(warp::path::end()) -// .and(warp::get()) -// .and(accept_json) -// .and_then(|id: String| async move { -// match Uuid::parse_str(&id) { -// Ok(uuid) => { -// let list = &packager::get_list(uuid); -// match list { -// Some(l) => Ok(warp::reply::json(l)), -// None => Err(warp::reject::not_found()), -// } -// } -// Err(e) => Err(warp::reject::custom(packager::router::InvalidUuid)), -// } -// }) -// .with(&cors) -// .recover(packager::router::handle_rejection); + // println!( + // "\nPackage list for trip {:?} at {:?}:", + // trip.name, trip.date + // ); + // for item in &trip.list.items { + // println!("{:?}", item); + // } -// let router = root.or(v1).or(lists).or(list); + // trip.list.items[0].set_status(packager::trip::TripItemStatus::Ready); + // trip.list.items[1].set_status(packager::trip::TripItemStatus::Packed); + // for item in &trip.list.items { + // println!("{:?}", item); + // } let router = packager::router::new(); - warp::serve(router).run(([127, 0, 0, 1], 9000)).await; } diff --git a/api/src/packagelist.rs b/api/src/packagelist.rs index c81801e..2d5ae98 100644 --- a/api/src/packagelist.rs +++ b/api/src/packagelist.rs @@ -1,9 +1,9 @@ use serde::ser::{SerializeStruct, Serializer}; -use serde::{Deserialize, Serialize}; +use serde::{Serialize}; use uuid::Uuid; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub enum Duration { None, @@ -16,8 +16,7 @@ impl Duration { } } -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Debug)] pub enum Period { Daily(i32), Weekly(i32), @@ -52,8 +51,7 @@ impl Serialize for Period { } } -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Debug)] pub enum ItemUsage { Singleton, Periodic(Period), @@ -86,9 +84,7 @@ impl Serialize for ItemUsage { } } - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Debug)] pub enum ItemSize { None, Pack(i32), @@ -135,7 +131,7 @@ impl ItemSize { } } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct PreparationStep { name: String, @@ -150,7 +146,7 @@ impl PreparationStep { } } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub enum Preparation { None, @@ -163,8 +159,7 @@ impl Preparation { } } - -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct PackageItem { pub id: Uuid, @@ -210,7 +205,7 @@ impl PackageItem { } } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct PackageList { pub id: Uuid, @@ -223,4 +218,3 @@ impl PackageList { PackageList { id, name, items } } } - diff --git a/api/src/router.rs b/api/src/router.rs index 86670f5..a4cf513 100644 --- a/api/src/router.rs +++ b/api/src/router.rs @@ -1,7 +1,10 @@ -use std::convert::Infallible; use serde::Serialize; +use std::convert::Infallible; + use warp; use warp::http::StatusCode; +use warp::Filter; + use uuid::Uuid; #[derive(Debug)] @@ -20,23 +23,19 @@ pub fn new() -> warp::filters::BoxedFilter<(impl warp::Reply,)> { let accept_json = warp::header::exact("accept", "application/json"); let cors = warp::cors().allow_any_origin(); - let root = warp::path::end() - .map(|| "Hi") - .recover(handle_rejection); + let root = warp::path::end().map(|| "Hi"); let v1 = warp::path!("v1") .and(warp::get()) .and(warp::path::end()) - .map(warp::reply) - .recover(handle_rejection); + .map(warp::reply); let lists = warp::path!("v1" / "lists") .and(warp::path::end()) .and(warp::get()) .and(accept_json) .map(|| warp::reply::json(&super::get_lists())) - .with(&cors) - .recover(handle_rejection); + .with(&cors); let list = warp::path!("v1" / "lists" / String) .and(warp::path::end()) @@ -51,15 +50,24 @@ pub fn new() -> warp::filters::BoxedFilter<(impl warp::Reply,)> { None => Err(warp::reject::not_found()), } } - Err(e) => Err(warp::reject::custom(InvalidUuid)), + Err(_) => Err(warp::reject::custom(InvalidUuid)), } }) - .with(&cors) - .recover(handle_rejection); + .with(&cors); - let routes = root.or(v1).or(lists).or(list).boxed(); + let trips = warp::path!("v1" / "trips") + .and(warp::path::end()) + .and(warp::get()) + .and(accept_json) + .map(|| warp::reply::json(&super::get_trips())) + .with(&cors); - routes + root.or(v1) + .or(lists) + .or(list) + .or(trips) + .recover(handle_rejection) + .boxed() } // See https://github.com/seanmonstar/warp/blob/master/examples/rejections.rs @@ -73,7 +81,7 @@ async fn handle_rejection(err: warp::Rejection) -> Result() { + } else if let Some(_) = err.find::() { message = "BAD_REQUEST"; code = StatusCode::BAD_REQUEST; } else if let Some(_) = err.find::() { diff --git a/api/src/trip.rs b/api/src/trip.rs new file mode 100644 index 0000000..5c24e83 --- /dev/null +++ b/api/src/trip.rs @@ -0,0 +1,76 @@ +use uuid::Uuid; +use serde::{Serialize}; + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub enum TripItemStatus { + Pending, + Ready, + Packed, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct TripItem<'a> { + pub id: Uuid, + + pub package_item: &'a super::PackageItem, + pub status: TripItemStatus, +} + +impl TripItem<'_> { + pub fn from_package_item(id: Uuid, package_item: &super::PackageItem) -> TripItem { + TripItem { + id, + package_item, + status: TripItemStatus::Pending, + } + } + + pub fn set_status(&mut self, status: TripItemStatus) { + self.status = status; + } +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct TripList<'a> { + pub id: Uuid, + pub items: Vec>, +} + +impl<'a> TripList<'a> { + pub fn from_package_list(id: Uuid, list: &'a super::PackageList) -> TripList<'a> { + let mut items = Vec::new(); + for item in &list.items { + items.push(TripItem::from_package_item(Uuid::new_v4(), item)); + } + + TripList { id, items } + } +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Trip { + pub id: Uuid, + pub name: String, + pub date: String, + pub package_list_ids: Vec, +} + +impl Trip { + pub fn from_package_list( + id: Uuid, + name: String, + date: String, + package_list_ids: Vec, + ) -> Trip { + Trip { + id, + name, + date, + package_list_ids, + } + } +}