From 7340a04d974f28cc44d9cd1d5d956baa413a28aa Mon Sep 17 00:00:00 2001
From: Abhijit Roy <dalvath3700@gmail.com>
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 <dalvath3700@gmail.com>
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 <dalvath3700@gmail.com>
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<String> = Lazy::new(|| format!("{}/recipes", API_BASE_URL));
+
+#[derive(Deserialize, Debug)]
+pub struct GetAllRecipesResponse {
+	pub recipes: Vec<Recipe>,
+	pub total: u32,
+	pub skip: u32,
+	pub limit: u32,
+}
+
+#[derive(Deserialize, Debug)]
+pub struct Recipe {
+	pub id: u32,
+	pub name: Option<String>,
+	pub ingredients: Option<Vec<String>>,
+	pub instructions: Option<Vec<String>>,
+	#[serde(rename = "prepTimeMinutes")]
+	pub prep_time_mins: Option<u32>,
+	#[serde(rename = "cookTimeMinutes")]
+	pub cook_time_mins: Option<u32>,
+	pub servings: Option<u32>,
+	// TODO: convert the Easy, Difficulty to enum
+	pub difficulty: Option<String>,
+	pub cuisine: Option<String>,
+	#[serde(rename = "caloriesPerServing")]
+	pub calories_per_serving: Option<u32>,
+	pub tags: Option<Vec<String>>,
+	#[serde(rename = "userId")]
+	pub user_id: Option<u32>,
+	pub image: Option<String>,
+	pub rating: Option<f32>,
+	#[serde(rename = "reviewCount")]
+	pub review_count: Option<u32>,
+	#[serde(rename = "mealType")]
+	pub meal_type: Option<Vec<String>>,
+}
+
+impl DummyJsonClient {
+	/// Get all recipes
+	pub async fn get_all_recipes(&self) -> Result<GetAllRecipesResponse, reqwest::Error> {
+		self.client
+			.get(RECIPES_BASE_URL.as_str())
+			.send()
+			.await?
+			.json::<GetAllRecipesResponse>()
+			.await
+	}
+
+	/// Get recipe by id
+	pub async fn get_recipe_by_id(&self, id: u32) -> Result<Recipe, reqwest::Error> {
+		self.client
+			.get(format!("{}/{}", &*RECIPES_BASE_URL, id))
+			.send()
+			.await?
+			.json::<Recipe>()
+			.await
+	}
+
+	/// Search recipes
+	pub async fn search_recipes(
+		&self,
+		query: &str,
+	) -> Result<GetAllRecipesResponse, reqwest::Error> {
+		self.client
+			.get(format!("{}/search?q={}", &*RECIPES_BASE_URL, query))
+			.send()
+			.await?
+			.json::<GetAllRecipesResponse>()
+			.await
+	}
+
+	/// Limit and skip recipes
+	pub async fn limit_and_skip_recipes(
+		&self,
+		limit: u32,
+		skip: u32,
+		selects: &str,
+	) -> Result<GetAllRecipesResponse, reqwest::Error> {
+		self.client
+			.get(format!(
+				"{}/?limit={}&skip={}&select={}",
+				&*RECIPES_BASE_URL, limit, skip, selects
+			))
+			.send()
+			.await?
+			.json::<GetAllRecipesResponse>()
+			.await
+	}
+
+	/// Sort recipes
+	pub async fn sort_recipes(
+		&self,
+		sort_by: &str,
+		// TODO: convert the asc, desc to enum
+		order: &str,
+	) -> Result<GetAllRecipesResponse, reqwest::Error> {
+		self.client
+			.get(format!("{}/?sortBy={}&order={}", &*RECIPES_BASE_URL, sort_by, order))
+			.send()
+			.await?
+			.json::<GetAllRecipesResponse>()
+			.await
+	}
+
+	/// Get recipes tags
+	pub async fn get_recipes_tags(&self) -> Result<Vec<String>, reqwest::Error> {
+		self.client
+			.get(format!("{}/tags", &*RECIPES_BASE_URL))
+			.send()
+			.await?
+			.json::<Vec<String>>()
+			.await
+	}
+
+	/// Get recipes by tags
+	pub async fn get_recipes_by_tags(
+		&self,
+		tags: &str,
+	) -> Result<GetAllRecipesResponse, reqwest::Error> {
+		self.client
+			.get(format!("{}/tag/{}", &*RECIPES_BASE_URL, tags))
+			.send()
+			.await?
+			.json::<GetAllRecipesResponse>()
+			.await
+	}
+
+	/// Get recipes by meal type
+	pub async fn get_recipes_by_meal_type(
+		&self,
+		meal_type: &str,
+	) -> Result<GetAllRecipesResponse, reqwest::Error> {
+		self.client
+			.get(format!("{}/meal-type/{}", &*RECIPES_BASE_URL, meal_type))
+			.send()
+			.await?
+			.json::<GetAllRecipesResponse>()
+			.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());
+	}
+}