From e068143f60b8cdd05e2cd2367ce1d0f114e16ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Wed, 3 Apr 2024 09:55:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(controller):=E5=A2=9E=E5=8A=A0=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E5=8A=9F=E8=83=BD=E4=BB=A5=E5=8F=8A=E4=BA=A7?= =?UTF-8?q?=E5=93=81=E6=A3=80=E7=B4=A2=E6=8E=A7=E5=88=B6=E5=99=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- license_server/src/controllers/license.rs | 0 license_server/src/controllers/mod.rs | 5 ++- license_server/src/controllers/products.rs | 43 ++++++++++++++++++++++ license_server/src/main.rs | 2 + license_server/src/products.rs | 4 +- license_server/src/utils.rs | 8 ++++ license_server/src/vo/mod.rs | 3 ++ license_server/src/vo/shared.rs | 12 ++++++ 8 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 license_server/src/controllers/license.rs create mode 100644 license_server/src/controllers/products.rs create mode 100644 license_server/src/utils.rs create mode 100644 license_server/src/vo/mod.rs create mode 100644 license_server/src/vo/shared.rs diff --git a/license_server/src/controllers/license.rs b/license_server/src/controllers/license.rs new file mode 100644 index 0000000..e69de29 diff --git a/license_server/src/controllers/mod.rs b/license_server/src/controllers/mod.rs index c54740a..af04848 100644 --- a/license_server/src/controllers/mod.rs +++ b/license_server/src/controllers/mod.rs @@ -1,8 +1,11 @@ +mod license; +mod products; + use axum::Router; /// 生成可迭代的转化为路由定义的控制器列表。 pub fn controllers() -> Box>> { - let controllers: Vec> = vec![]; + let controllers: Vec> = vec![Box::new(products::ProductsController::init().into())]; Box::from(controllers.into_iter()) } diff --git a/license_server/src/controllers/products.rs b/license_server/src/controllers/products.rs new file mode 100644 index 0000000..70cc13d --- /dev/null +++ b/license_server/src/controllers/products.rs @@ -0,0 +1,43 @@ +use axum::{extract::Query, http::StatusCode, response::IntoResponse, routing, Json, Router}; + +use tracing::info; + +use crate::vo::KeywordQuery; + +pub struct ProductsController { + routes: Router, +} + +impl Into for ProductsController { + fn into(self) -> Router { + self.routes + } +} + +impl ProductsController { + pub fn init() -> Self { + let routes = Router::new().route("/products", routing::get(search_products)); + + Self { routes } + } +} + +async fn search_products(Query(keyword_query): Query) -> impl IntoResponse { + info!(keyword = keyword_query.keyword(), "search products"); + let response_products = { + if let Some(keyword) = keyword_query.keyword() { + crate::products::get() + .iter() + .filter(|&p| p.name.to_lowercase().contains(&(keyword.to_lowercase()))) + .collect::>() + } else { + crate::products::get().iter().collect::>() + } + }; + let products_length = response_products.len(); + info!( + fetched_length = ?products_length, + "retrieved {} products", products_length + ); + (StatusCode::OK, Json(response_products)) +} diff --git a/license_server/src/main.rs b/license_server/src/main.rs index cd4aa70..f6bbc38 100644 --- a/license_server/src/main.rs +++ b/license_server/src/main.rs @@ -7,6 +7,8 @@ mod controllers; mod logging; mod products; mod server_routes; +mod utils; +mod vo; #[tokio::main] async fn main() { diff --git a/license_server/src/products.rs b/license_server/src/products.rs index 4f33fd9..5e4d99d 100644 --- a/license_server/src/products.rs +++ b/license_server/src/products.rs @@ -1,9 +1,9 @@ use std::sync::OnceLock; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use tokio::{fs::File, io::AsyncReadExt}; -#[derive(Debug, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Product { pub id: String, pub name: String, diff --git a/license_server/src/utils.rs b/license_server/src/utils.rs new file mode 100644 index 0000000..b490034 --- /dev/null +++ b/license_server/src/utils.rs @@ -0,0 +1,8 @@ +pub fn empty_to_none>(s: S) -> Option { + let s = s.into(); + if s.is_empty() { + None + } else { + Some(s) + } +} diff --git a/license_server/src/vo/mod.rs b/license_server/src/vo/mod.rs new file mode 100644 index 0000000..01a41e3 --- /dev/null +++ b/license_server/src/vo/mod.rs @@ -0,0 +1,3 @@ +mod shared; + +pub use shared::*; diff --git a/license_server/src/vo/shared.rs b/license_server/src/vo/shared.rs new file mode 100644 index 0000000..35fabf5 --- /dev/null +++ b/license_server/src/vo/shared.rs @@ -0,0 +1,12 @@ +use serde::Deserialize; + +#[derive(Debug, Clone, Deserialize)] +pub struct KeywordQuery { + pub keyword: Option, +} + +impl KeywordQuery { + pub fn keyword(&self) -> Option { + self.keyword.clone().and_then(crate::utils::empty_to_none) + } +}