dummy_json_rs/
recipes.rs

1use crate::{DummyJsonClient, API_BASE_URL};
2use once_cell::sync::Lazy;
3use serde::Deserialize;
4
5static RECIPES_BASE_URL: Lazy<String> = Lazy::new(|| format!("{}/recipes", API_BASE_URL));
6
7#[derive(Deserialize, Debug)]
8pub struct GetAllRecipesResponse {
9	pub recipes: Vec<Recipe>,
10	pub total: u32,
11	pub skip: u32,
12	pub limit: u32,
13}
14
15#[derive(Deserialize, Debug)]
16pub struct Recipe {
17	pub id: u32,
18	pub name: Option<String>,
19	pub ingredients: Option<Vec<String>>,
20	pub instructions: Option<Vec<String>>,
21	#[serde(rename = "prepTimeMinutes")]
22	pub prep_time_mins: Option<u32>,
23	#[serde(rename = "cookTimeMinutes")]
24	pub cook_time_mins: Option<u32>,
25	pub servings: Option<u32>,
26	// TODO: convert the Easy, Difficulty to enum
27	pub difficulty: Option<String>,
28	pub cuisine: Option<String>,
29	#[serde(rename = "caloriesPerServing")]
30	pub calories_per_serving: Option<u32>,
31	pub tags: Option<Vec<String>>,
32	#[serde(rename = "userId")]
33	pub user_id: Option<u32>,
34	pub image: Option<String>,
35	pub rating: Option<f32>,
36	#[serde(rename = "reviewCount")]
37	pub review_count: Option<u32>,
38	#[serde(rename = "mealType")]
39	pub meal_type: Option<Vec<String>>,
40}
41
42impl DummyJsonClient {
43	/// Get all recipes
44	pub async fn get_all_recipes(&self) -> Result<GetAllRecipesResponse, reqwest::Error> {
45		self.client
46			.get(RECIPES_BASE_URL.as_str())
47			.send()
48			.await?
49			.json::<GetAllRecipesResponse>()
50			.await
51	}
52
53	/// Get recipe by id
54	pub async fn get_recipe_by_id(&self, id: u32) -> Result<Recipe, reqwest::Error> {
55		self.client
56			.get(format!("{}/{}", RECIPES_BASE_URL.as_str(), id))
57			.send()
58			.await?
59			.json::<Recipe>()
60			.await
61	}
62
63	/// Search recipes
64	pub async fn search_recipes(
65		&self,
66		query: &str,
67	) -> Result<GetAllRecipesResponse, reqwest::Error> {
68		self.client
69			.get(format!("{}/search?q={}", RECIPES_BASE_URL.as_str(), query))
70			.send()
71			.await?
72			.json::<GetAllRecipesResponse>()
73			.await
74	}
75
76	/// Limit and skip recipes
77	pub async fn limit_and_skip_recipes(
78		&self,
79		limit: u32,
80		skip: u32,
81		selects: &str,
82	) -> Result<GetAllRecipesResponse, reqwest::Error> {
83		self.client
84			.get(format!(
85				"{}/?limit={}&skip={}&select={}",
86				RECIPES_BASE_URL.as_str(),
87				limit,
88				skip,
89				selects
90			))
91			.send()
92			.await?
93			.json::<GetAllRecipesResponse>()
94			.await
95	}
96
97	/// Sort recipes
98	pub async fn sort_recipes(
99		&self,
100		sort_by: &str,
101		// TODO: convert the asc, desc to enum
102		order: &str,
103	) -> Result<GetAllRecipesResponse, reqwest::Error> {
104		self.client
105			.get(format!("{}/?sortBy={}&order={}", RECIPES_BASE_URL.as_str(), sort_by, order))
106			.send()
107			.await?
108			.json::<GetAllRecipesResponse>()
109			.await
110	}
111
112	/// Get recipes tags
113	pub async fn get_recipes_tags(&self) -> Result<Vec<String>, reqwest::Error> {
114		self.client
115			.get(format!("{}/tags", RECIPES_BASE_URL.as_str()))
116			.send()
117			.await?
118			.json::<Vec<String>>()
119			.await
120	}
121
122	/// Get recipes by tags
123	pub async fn get_recipes_by_tags(
124		&self,
125		tags: &str,
126	) -> Result<GetAllRecipesResponse, reqwest::Error> {
127		self.client
128			.get(format!("{}/tag/{}", RECIPES_BASE_URL.as_str(), tags))
129			.send()
130			.await?
131			.json::<GetAllRecipesResponse>()
132			.await
133	}
134
135	/// Get recipes by meal type
136	pub async fn get_recipes_by_meal_type(
137		&self,
138		meal_type: &str,
139	) -> Result<GetAllRecipesResponse, reqwest::Error> {
140		self.client
141			.get(format!("{}/meal-type/{}", RECIPES_BASE_URL.as_str(), meal_type))
142			.send()
143			.await?
144			.json::<GetAllRecipesResponse>()
145			.await
146	}
147}