dummy_json_rs/
products.rs

1use crate::{DummyJsonClient, API_BASE_URL};
2use once_cell::sync::Lazy;
3use serde::{Deserialize, Serialize};
4
5static PRODUCTS_BASE_URL: Lazy<String> = Lazy::new(|| format!("{}/products", API_BASE_URL));
6
7#[derive(Deserialize, Debug)]
8pub struct Product {
9	pub id: u32,
10	#[serde(flatten)]
11	pub other_fields: AddProduct,
12}
13
14#[derive(Serialize, Deserialize, Debug, Default)]
15pub struct AddProduct {
16	pub title: String,
17	pub description: Option<String>,
18	pub price: Option<f32>,
19	#[serde(rename = "discountPercentage")]
20	pub discount_percentage: Option<f32>,
21	pub rating: Option<f32>,
22	pub stock: Option<u32>,
23	pub tags: Option<Vec<String>>,
24	// FIXME: Not sure, why the actual API response missing 'brand' field
25	// resulting in error.
26	// pub brand: Option<String>,
27	pub sku: Option<String>,
28	pub weight: Option<u16>,
29	pub dimensions: Option<Dimension>,
30	#[serde(rename = "warrantyInformation")]
31	pub warranty_info: Option<String>,
32	#[serde(rename = "shippingInformation")]
33	pub shipping_info: Option<String>,
34	#[serde(rename = "availabilityStatus")]
35	pub availability_status: Option<String>,
36	pub reviews: Option<Vec<Review>>,
37	#[serde(rename = "returnPolicy")]
38	pub return_policy: Option<String>,
39	#[serde(rename = "minimumOrderQuantity")]
40	pub min_order_qty: Option<u16>,
41	pub meta: Option<Meta>,
42	pub images: Option<Vec<String>>,
43	pub thumbnail: Option<String>,
44}
45
46#[derive(Serialize, Deserialize, Debug)]
47pub struct Dimension {
48	pub width: f32,
49	pub height: f32,
50	pub depth: f32,
51}
52
53#[derive(Serialize, Deserialize, Debug)]
54pub struct Review {
55	pub rating: u8,
56	pub comment: String,
57	pub date: String,
58	#[serde(rename = "reviewerName")]
59	pub reviewer_name: String,
60	#[serde(rename = "reviewerEmail")]
61	pub reviewer_email: String,
62}
63
64#[derive(Serialize, Deserialize, Debug)]
65pub struct Meta {
66	#[serde(rename = "createdAt")]
67	pub created_at: String,
68	#[serde(rename = "updatedAt")]
69	pub updated_at: String,
70	pub barcode: String,
71	#[serde(rename = "qrCode")]
72	pub qr_code: String,
73}
74
75#[derive(Deserialize, Debug)]
76pub struct GetAllProductsResponse {
77	pub products: Vec<Product>,
78	pub total: u32,
79	pub skip: u32,
80	pub limit: u32,
81}
82
83#[derive(Deserialize, Debug)]
84pub struct ProductCategory {
85	pub slug: String,
86	pub name: String,
87	pub url: String,
88}
89
90#[derive(Deserialize, Debug)]
91pub struct DeleteProductResponse {
92	#[serde(flatten)]
93	pub other_fields: Product,
94	#[serde(rename = "isDeleted")]
95	pub is_deleted: bool,
96	#[serde(rename = "deletedOn")]
97	pub deleted_on: String,
98}
99
100impl DummyJsonClient {
101	/// Get all products
102	pub async fn get_all_products(&self) -> Result<GetAllProductsResponse, reqwest::Error> {
103		let response = self.client.get(PRODUCTS_BASE_URL.as_str()).send().await?;
104		response.json::<GetAllProductsResponse>().await
105	}
106
107	/// Get product by id
108	pub async fn get_product_by_id(&self, id: u32) -> Result<Product, reqwest::Error> {
109		let url = &format!("{}/{}", PRODUCTS_BASE_URL.as_str(), id);
110		let response = self.client.get(url).send().await?;
111		response.json::<Product>().await
112	}
113
114	/// Search products
115	pub async fn search_products(
116		&self,
117		query: &str,
118	) -> Result<GetAllProductsResponse, reqwest::Error> {
119		let url = &format!("{}/search?q={}", PRODUCTS_BASE_URL.as_str(), query);
120		let response = self.client.get(url).send().await?;
121		response.json::<GetAllProductsResponse>().await
122	}
123
124	/// Limit and skip products
125	pub async fn limit_and_skip_products(
126		&self,
127		limit: u32,
128		skip: u32,
129		selects: &str,
130	) -> Result<GetAllProductsResponse, reqwest::Error> {
131		let url = &format!(
132			"{}/?limit={}&skip={}&select={}",
133			PRODUCTS_BASE_URL.as_str(),
134			limit,
135			skip,
136			selects
137		);
138		let response = self.client.get(url).send().await?;
139		response.json::<GetAllProductsResponse>().await
140	}
141
142	/// Sort products by field
143	pub async fn sort_products_by(
144		&self,
145		field: &str,
146		order: &str,
147	) -> Result<GetAllProductsResponse, reqwest::Error> {
148		let url = &format!("{}/?sortBy={}&order={}", PRODUCTS_BASE_URL.as_str(), field, order);
149		let response = self.client.get(url).send().await?;
150		response.json::<GetAllProductsResponse>().await
151	}
152
153	/// Get product categories
154	pub async fn get_product_categories(&self) -> Result<Vec<ProductCategory>, reqwest::Error> {
155		let url = &format!("{}/categories", PRODUCTS_BASE_URL.as_str());
156		let response = self.client.get(url).send().await?;
157		response.json::<Vec<ProductCategory>>().await
158	}
159
160	/// Get product categories list
161	pub async fn get_product_categories_list(&self) -> Result<Vec<String>, reqwest::Error> {
162		let url = &format!("{}/category-list", PRODUCTS_BASE_URL.as_str());
163		let response = self.client.get(url).send().await?;
164		response.json::<Vec<String>>().await
165	}
166
167	/// Get products by category
168	pub async fn get_products_by_category(
169		&self,
170		category: &str,
171	) -> Result<GetAllProductsResponse, reqwest::Error> {
172		let url = &format!("{}/category/{}", PRODUCTS_BASE_URL.as_str(), category);
173		let response = self.client.get(url).send().await?;
174		response.json::<GetAllProductsResponse>().await
175	}
176
177	/// Add product
178	pub async fn add_product(&self, product: &AddProduct) -> Result<Product, reqwest::Error> {
179		let url = &format!("{}/add", PRODUCTS_BASE_URL.as_str());
180		let response = self.client.post(url).json(product).send().await?;
181		response.json::<Product>().await
182	}
183
184	/// Update product
185	pub async fn update_product(
186		&self,
187		id: u32,
188		product: &AddProduct,
189	) -> Result<Product, reqwest::Error> {
190		let url = &format!("{}/{}", PRODUCTS_BASE_URL.as_str(), id);
191		let response = self.client.put(url).json(product).send().await?;
192		response.json::<Product>().await
193	}
194
195	/// Delete product
196	pub async fn delete_product(&self, id: u32) -> Result<DeleteProductResponse, reqwest::Error> {
197		let url = &format!("{}/{}", PRODUCTS_BASE_URL.as_str(), id);
198		let response = self.client.delete(url).send().await?;
199		response.json::<DeleteProductResponse>().await
200	}
201}