From 8465d2d3791cd560898b6bd21c43a9f82451519f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=9B=8B=E7=96=BC=E7=9A=84=E8=9B=8B=E8=9B=8B?= Date: Wed, 8 Nov 2023 00:40:07 +0800 Subject: [PATCH] refactor(service/http): Add HttpConfig to implement ConfigDeserializer (#3507) * add HttpConfig * aa * add pub to Config member * add docstring for pub member --- core/src/services/http/backend.rs | 75 ++++++++++++++++++++----------- core/src/services/http/mod.rs | 1 + core/src/services/mod.rs | 2 + 3 files changed, 51 insertions(+), 27 deletions(-) diff --git a/core/src/services/http/backend.rs b/core/src/services/http/backend.rs index 233237f8721f..879f691b26e6 100644 --- a/core/src/services/http/backend.rs +++ b/core/src/services/http/backend.rs @@ -32,25 +32,48 @@ use super::error::parse_error; use crate::raw::*; use crate::*; +use serde::Deserialize; + +/// Config for Http service support. +#[derive(Default, Deserialize)] +#[serde(default)] +#[non_exhaustive] +pub struct HttpConfig { + /// endpoint of this backend + pub endpoint: Option, + /// username of this backend + pub username: Option, + /// password of this backend + pub password: Option, + /// token of this backend + pub token: Option, + /// root of this backend + pub root: Option, +} + +impl Debug for HttpConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut de = f.debug_struct("HttpConfig"); + de.field("endpoint", &self.endpoint); + de.field("root", &self.root); + + de.finish_non_exhaustive() + } +} + /// HTTP Read-only service support like [Nginx](https://www.nginx.com/) and [Caddy](https://caddyserver.com/). #[doc = include_str!("docs.md")] #[derive(Default)] pub struct HttpBuilder { - endpoint: Option, - username: Option, - password: Option, - token: Option, - root: Option, + config: HttpConfig, http_client: Option, } impl Debug for HttpBuilder { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let mut de = f.debug_struct("Builder"); - de.field("endpoint", &self.endpoint); - de.field("root", &self.root); + let mut de = f.debug_struct("HttpBuilder"); - de.finish() + de.field("config", &self.config).finish() } } @@ -59,7 +82,7 @@ impl HttpBuilder { /// /// For example: `https://example.com` pub fn endpoint(&mut self, endpoint: &str) -> &mut Self { - self.endpoint = if endpoint.is_empty() { + self.config.endpoint = if endpoint.is_empty() { None } else { Some(endpoint.to_string()) @@ -73,7 +96,7 @@ impl HttpBuilder { /// default: no password pub fn username(&mut self, username: &str) -> &mut Self { if !username.is_empty() { - self.username = Some(username.to_owned()); + self.config.username = Some(username.to_owned()); } self } @@ -83,7 +106,7 @@ impl HttpBuilder { /// default: no password pub fn password(&mut self, password: &str) -> &mut Self { if !password.is_empty() { - self.password = Some(password.to_owned()); + self.config.password = Some(password.to_owned()); } self } @@ -93,14 +116,14 @@ impl HttpBuilder { /// default: no access token pub fn token(&mut self, token: &str) -> &mut Self { if !token.is_empty() { - self.token = Some(token.to_owned()); + self.config.token = Some(token.to_owned()); } self } /// Set root path of http backend. pub fn root(&mut self, root: &str) -> &mut Self { - self.root = if root.is_empty() { + self.config.root = if root.is_empty() { None } else { Some(root.to_string()) @@ -126,21 +149,19 @@ impl Builder for HttpBuilder { type Accessor = HttpBackend; fn from_map(map: HashMap) -> Self { - let mut builder = HttpBuilder::default(); - - map.get("root").map(|v| builder.root(v)); - map.get("endpoint").map(|v| builder.endpoint(v)); - map.get("username").map(|v| builder.username(v)); - map.get("password").map(|v| builder.password(v)); - map.get("token").map(|v| builder.token(v)); + let config = HttpConfig::deserialize(ConfigDeserializer::new(map)) + .expect("config deserialize must succeed"); - builder + HttpBuilder { + config, + http_client: None, + } } fn build(&mut self) -> Result { debug!("backend build started: {:?}", &self); - let endpoint = match &self.endpoint { + let endpoint = match &self.config.endpoint { Some(v) => v, None => { return Err(Error::new(ErrorKind::ConfigInvalid, "endpoint is empty") @@ -148,7 +169,7 @@ impl Builder for HttpBuilder { } }; - let root = normalize_root(&self.root.take().unwrap_or_default()); + let root = normalize_root(&self.config.root.take().unwrap_or_default()); debug!("backend use root {}", root); let client = if let Some(client) = self.http_client.take() { @@ -161,13 +182,13 @@ impl Builder for HttpBuilder { }; let mut auth = None; - if let Some(username) = &self.username { + if let Some(username) = &self.config.username { auth = Some(format_authorization_by_basic( username, - self.password.as_deref().unwrap_or_default(), + self.config.password.as_deref().unwrap_or_default(), )?); } - if let Some(token) = &self.token { + if let Some(token) = &self.config.token { auth = Some(format_authorization_by_bearer(token)?) } diff --git a/core/src/services/http/mod.rs b/core/src/services/http/mod.rs index bf61ce4640de..7424d97c2b9b 100644 --- a/core/src/services/http/mod.rs +++ b/core/src/services/http/mod.rs @@ -17,5 +17,6 @@ mod backend; pub use backend::HttpBuilder as Http; +pub use backend::HttpConfig; mod error; diff --git a/core/src/services/mod.rs b/core/src/services/mod.rs index 042f5660c8c8..475cd57f3de3 100644 --- a/core/src/services/mod.rs +++ b/core/src/services/mod.rs @@ -83,6 +83,8 @@ pub use hdfs::Hdfs; mod http; #[cfg(feature = "services-http")] pub use self::http::Http; +#[cfg(feature = "services-http")] +pub use self::http::HttpConfig; #[cfg(feature = "services-ipfs")] mod ipfs;