api.rs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #![allow(unused)]
  2. use std::fmt::Display;
  3. use chrono::{DateTime, Utc};
  4. use serde::{Deserialize, Serialize};
  5. #[derive(Serialize, Deserialize, PartialEq, Clone, Debug, Default)]
  6. pub(crate) struct Product {
  7. pub(crate) id: u32,
  8. pub(crate) title: String,
  9. pub(crate) price: f32,
  10. pub(crate) description: String,
  11. pub(crate) category: String,
  12. pub(crate) image: String,
  13. pub(crate) rating: Rating,
  14. }
  15. #[derive(Serialize, Deserialize, PartialEq, Clone, Debug, Default)]
  16. pub(crate) struct Rating {
  17. pub(crate) rate: f32,
  18. pub(crate) count: u32,
  19. }
  20. impl Display for Rating {
  21. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  22. let rounded = self.rate.round() as usize;
  23. for _ in 0..rounded {
  24. "★".fmt(f)?;
  25. }
  26. for _ in 0..(5 - rounded) {
  27. "☆".fmt(f)?;
  28. }
  29. write!(f, " ({:01}) ({} ratings)", self.rate, self.count)?;
  30. Ok(())
  31. }
  32. }
  33. #[allow(unused)]
  34. #[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd)]
  35. pub(crate) enum Sort {
  36. Descending,
  37. Ascending,
  38. }
  39. impl Display for Sort {
  40. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  41. match self {
  42. Sort::Descending => write!(f, "desc"),
  43. Sort::Ascending => write!(f, "asc"),
  44. }
  45. }
  46. }
  47. // Cache up to 100 requests, invalidating them after 60 seconds
  48. pub(crate) async fn fetch_user_carts(user_id: usize) -> Result<Vec<Cart>, reqwest::Error> {
  49. reqwest::get(format!(
  50. "https://fakestoreapi.com/carts/user/{user_id}?startdate=2019-12-10&enddate=2023-01-01"
  51. ))
  52. .await?
  53. .json()
  54. .await
  55. }
  56. // Cache up to 100 requests, invalidating them after 60 seconds
  57. pub(crate) async fn fetch_user(user_id: usize) -> dioxus::Result<Product> {
  58. Ok(
  59. reqwest::get(format!("https://fakestoreapi.com/users/{user_id}"))
  60. .await?
  61. .json()
  62. .await?,
  63. )
  64. }
  65. // Cache up to 100 requests, invalidating them after 60 seconds
  66. pub(crate) async fn fetch_product(product_id: usize) -> dioxus::Result<Product> {
  67. Ok(
  68. reqwest::get(format!("https://fakestoreapi.com/products/{product_id}"))
  69. .await?
  70. .json()
  71. .await?,
  72. )
  73. }
  74. // Cache up to 100 requests, invalidating them after 60 seconds
  75. pub(crate) async fn fetch_products(count: usize, sort: Sort) -> dioxus::Result<Vec<Product>> {
  76. Ok(reqwest::get(format!(
  77. "https://fakestoreapi.com/products/?sort={sort}&limit={count}"
  78. ))
  79. .await?
  80. .json()
  81. .await?)
  82. }
  83. #[derive(Serialize, Deserialize)]
  84. pub(crate) struct User {
  85. id: usize,
  86. email: String,
  87. username: String,
  88. password: String,
  89. name: FullName,
  90. phone: String,
  91. }
  92. impl User {
  93. async fn fetch_most_recent_cart(&self) -> Result<Option<Cart>, reqwest::Error> {
  94. let all_carts = fetch_user_carts(self.id).await?;
  95. Ok(all_carts.into_iter().max_by_key(|cart| cart.date))
  96. }
  97. }
  98. #[derive(Serialize, Deserialize)]
  99. struct FullName {
  100. firstname: String,
  101. lastname: String,
  102. }
  103. #[derive(Serialize, Deserialize, Clone)]
  104. pub(crate) struct Cart {
  105. id: usize,
  106. #[serde(rename = "userId")]
  107. user_id: usize,
  108. data: String,
  109. products: Vec<ProductInCart>,
  110. date: DateTime<Utc>,
  111. }
  112. impl Cart {
  113. async fn update_database(&mut self) -> Result<(), reqwest::Error> {
  114. let id = self.id;
  115. let client = reqwest::Client::new();
  116. *self = client
  117. .put(format!("https://fakestoreapi.com/carts/{id}"))
  118. .send()
  119. .await?
  120. .json()
  121. .await?;
  122. Ok(())
  123. }
  124. }
  125. #[derive(Serialize, Deserialize, Clone)]
  126. pub(crate) struct ProductInCart {
  127. #[serde(rename = "productId")]
  128. product_id: usize,
  129. quantity: usize,
  130. }
  131. impl ProductInCart {
  132. pub async fn fetch_product(&self) -> Result<Product, dioxus::CapturedError> {
  133. fetch_product(self.product_id).await
  134. }
  135. }