From 7340a04d974f28cc44d9cd1d5d956baa413a28aa Mon Sep 17 00:00:00 2001 From: Abhijit Roy Date: Thu, 31 Oct 2024 21:33:17 +0530 Subject: [PATCH 1/3] Add recipes.http --- api-requests/recipes.http | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 api-requests/recipes.http diff --git a/api-requests/recipes.http b/api-requests/recipes.http new file mode 100644 index 0000000..7ef8597 --- /dev/null +++ b/api-requests/recipes.http @@ -0,0 +1,43 @@ +@host=https://dummyjson.com/recipes + +### +# @name GetAllRecipes +GET {{host}} +Accept: application/json +Content-Type: application/json + +### +# @name GetRecipeById +GET {{host}}/1 +Accept: application/json +Content-Type: application/json + +### +# @name SearchRecipes +GET {{host}}/search?q=pizza +Accept: application/json +Content-Type: application/json + +### +# @name LimitAndSkipRecipes +GET {{host}}?limit=10&skip=10&select=name,image +Accept: application/json +Content-Type: application/json + +### +# @name SortRecipes +GET {{host}}?sortBy=name&order=asc +Accept: application/json +Content-Type: application/json + +### +# @name GetRecipesByTags +GET {{host}}/tags +Accept: application/json +Content-Type: application/json + +### +# @name GetRecipesByMealType +GET {{host}}/meal-type/snack +Accept: application/json +Content-Type: application/json \ No newline at end of file From 6006bd0f99560f69bb4969218a1db91e92fd3792 Mon Sep 17 00:00:00 2001 From: Abhijit Roy Date: Fri, 1 Nov 2024 12:41:54 +0530 Subject: [PATCH 2/3] Add to recipes.http --- api-requests/recipes.http | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/api-requests/recipes.http b/api-requests/recipes.http index 7ef8597..db0deed 100644 --- a/api-requests/recipes.http +++ b/api-requests/recipes.http @@ -31,13 +31,21 @@ Accept: application/json Content-Type: application/json ### -# @name GetRecipesByTags +# @name GetRecipesTags GET {{host}}/tags Accept: application/json Content-Type: application/json +### +# @name GetRecipesByTags +@tags=pakistani +GET {{host}}/tag/{{tags}} +Accept: application/json +Content-Type: application/json + ### # @name GetRecipesByMealType -GET {{host}}/meal-type/snack +@meal_type=snack +GET {{host}}/meal-type/{{meal_type}} Accept: application/json Content-Type: application/json \ No newline at end of file From e2cdc2a424f00544e232591879aa61983cd20258 Mon Sep 17 00:00:00 2001 From: Abhijit Roy Date: Fri, 1 Nov 2024 16:08:55 +0530 Subject: [PATCH 3/3] Add recipes (with tests) module --- api-requests/recipes.http | 2 +- src/lib.rs | 2 + src/recipes.rs | 144 ++++++++++++++++++++++++++++++++++++++ tests/recipes.rs | 67 ++++++++++++++++++ 4 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 src/recipes.rs create mode 100644 tests/recipes.rs diff --git a/api-requests/recipes.http b/api-requests/recipes.http index db0deed..74e6490 100644 --- a/api-requests/recipes.http +++ b/api-requests/recipes.http @@ -38,7 +38,7 @@ Content-Type: application/json ### # @name GetRecipesByTags -@tags=pakistani +@tags=biryani GET {{host}}/tag/{{tags}} Accept: application/json Content-Type: application/json diff --git a/src/lib.rs b/src/lib.rs index 0c62989..d100838 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,13 @@ mod auth; mod carts; mod products; +mod recipes; mod todos; pub use auth::*; pub use carts::*; pub use products::*; +pub use recipes::*; use reqwest::Client; pub use todos::*; diff --git a/src/recipes.rs b/src/recipes.rs new file mode 100644 index 0000000..7e51290 --- /dev/null +++ b/src/recipes.rs @@ -0,0 +1,144 @@ +use crate::{DummyJsonClient, API_BASE_URL}; +use once_cell::sync::Lazy; +use serde::Deserialize; + +static RECIPES_BASE_URL: Lazy = Lazy::new(|| format!("{}/recipes", API_BASE_URL)); + +#[derive(Deserialize, Debug)] +pub struct GetAllRecipesResponse { + pub recipes: Vec, + pub total: u32, + pub skip: u32, + pub limit: u32, +} + +#[derive(Deserialize, Debug)] +pub struct Recipe { + pub id: u32, + pub name: Option, + pub ingredients: Option>, + pub instructions: Option>, + #[serde(rename = "prepTimeMinutes")] + pub prep_time_mins: Option, + #[serde(rename = "cookTimeMinutes")] + pub cook_time_mins: Option, + pub servings: Option, + // TODO: convert the Easy, Difficulty to enum + pub difficulty: Option, + pub cuisine: Option, + #[serde(rename = "caloriesPerServing")] + pub calories_per_serving: Option, + pub tags: Option>, + #[serde(rename = "userId")] + pub user_id: Option, + pub image: Option, + pub rating: Option, + #[serde(rename = "reviewCount")] + pub review_count: Option, + #[serde(rename = "mealType")] + pub meal_type: Option>, +} + +impl DummyJsonClient { + /// Get all recipes + pub async fn get_all_recipes(&self) -> Result { + self.client + .get(RECIPES_BASE_URL.as_str()) + .send() + .await? + .json::() + .await + } + + /// Get recipe by id + pub async fn get_recipe_by_id(&self, id: u32) -> Result { + self.client + .get(format!("{}/{}", &*RECIPES_BASE_URL, id)) + .send() + .await? + .json::() + .await + } + + /// Search recipes + pub async fn search_recipes( + &self, + query: &str, + ) -> Result { + self.client + .get(format!("{}/search?q={}", &*RECIPES_BASE_URL, query)) + .send() + .await? + .json::() + .await + } + + /// Limit and skip recipes + pub async fn limit_and_skip_recipes( + &self, + limit: u32, + skip: u32, + selects: &str, + ) -> Result { + self.client + .get(format!( + "{}/?limit={}&skip={}&select={}", + &*RECIPES_BASE_URL, limit, skip, selects + )) + .send() + .await? + .json::() + .await + } + + /// Sort recipes + pub async fn sort_recipes( + &self, + sort_by: &str, + // TODO: convert the asc, desc to enum + order: &str, + ) -> Result { + self.client + .get(format!("{}/?sortBy={}&order={}", &*RECIPES_BASE_URL, sort_by, order)) + .send() + .await? + .json::() + .await + } + + /// Get recipes tags + pub async fn get_recipes_tags(&self) -> Result, reqwest::Error> { + self.client + .get(format!("{}/tags", &*RECIPES_BASE_URL)) + .send() + .await? + .json::>() + .await + } + + /// Get recipes by tags + pub async fn get_recipes_by_tags( + &self, + tags: &str, + ) -> Result { + self.client + .get(format!("{}/tag/{}", &*RECIPES_BASE_URL, tags)) + .send() + .await? + .json::() + .await + } + + /// Get recipes by meal type + pub async fn get_recipes_by_meal_type( + &self, + meal_type: &str, + ) -> Result { + self.client + .get(format!("{}/meal-type/{}", &*RECIPES_BASE_URL, meal_type)) + .send() + .await? + .json::() + .await + } +} diff --git a/tests/recipes.rs b/tests/recipes.rs new file mode 100644 index 0000000..8a7a843 --- /dev/null +++ b/tests/recipes.rs @@ -0,0 +1,67 @@ +mod recipes { + use dummy_json_rs::DummyJsonClient; + + #[tokio::test] + async fn get_all_recipes() { + let client = DummyJsonClient::default(); + let response = client.get_all_recipes().await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn get_recipe_by_id() { + let client = DummyJsonClient::default(); + let response = client.get_recipe_by_id(1).await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn search_recipes() { + let client = DummyJsonClient::default(); + let response = client.search_recipes("pizza").await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn limit_and_skip_recipes() { + let client = DummyJsonClient::default(); + let response = client.limit_and_skip_recipes(10, 10, "name,image").await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn sort_recipes() { + let client = DummyJsonClient::default(); + let response = client.sort_recipes("name", "asc").await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn get_recipes_tags() { + let client = DummyJsonClient::default(); + let response = client.get_recipes_tags().await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn get_recipes_by_tags() { + let client = DummyJsonClient::default(); + let response = client.get_recipes_by_tags("biryani").await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } + + #[tokio::test] + async fn get_recipes_by_meal_type() { + let client = DummyJsonClient::default(); + let response = client.get_recipes_by_meal_type("snack").await; + assert!(response.is_ok()); + println!("{:#?}", response.unwrap()); + } +}