From ad8c51a2079d4c103c32b1ea5b8ed24ed62652a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=97=8D+85CD?= <50108258+kwaa@users.noreply.github.com> Date: Sat, 30 Dec 2023 18:41:50 +0800 Subject: [PATCH] refactor(services/webdav): Add WebdavConfig to implement ConfigDeserializer (#3846) * refactor(services/webdav): Add WebdavConfig to implement ConfigDeserializer * fix(services/webdav): resolve conversation --- core/src/services/mod.rs | 2 + core/src/services/webdav/backend.rs | 64 ++++++++++++++++++++--------- core/src/services/webdav/mod.rs | 1 + 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/core/src/services/mod.rs b/core/src/services/mod.rs index e9e42675b37..f0d086d6e77 100644 --- a/core/src/services/mod.rs +++ b/core/src/services/mod.rs @@ -206,6 +206,8 @@ pub use supabase::Supabase; mod webdav; #[cfg(feature = "services-webdav")] pub use webdav::Webdav; +#[cfg(feature = "services-webdav")] +pub use webdav::WebdavConfig; #[cfg(feature = "services-webhdfs")] mod webhdfs; diff --git a/core/src/services/webdav/backend.rs b/core/src/services/webdav/backend.rs index 36a96094076..e1a3e895cfa 100644 --- a/core/src/services/webdav/backend.rs +++ b/core/src/services/webdav/backend.rs @@ -29,6 +29,7 @@ use http::Request; use http::Response; use http::StatusCode; use log::debug; +use serde::Deserialize; use super::error::parse_error; use super::lister::Multistatus; @@ -37,25 +38,50 @@ use super::writer::WebdavWriter; use crate::raw::*; use crate::*; +/// Config for [WebDAV](https://datatracker.ietf.org/doc/html/rfc4918) backend support. +#[derive(Default, Deserialize)] +#[serde(default)] +#[non_exhaustive] +pub struct WebdavConfig { + /// 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 WebdavConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut d = f.debug_struct("WebdavConfig"); + + d.field("endpoint", &self.endpoint) + .field("username", &self.username) + .field("root", &self.root); + + d.finish_non_exhaustive() + } +} + /// [WebDAV](https://datatracker.ietf.org/doc/html/rfc4918) backend support. #[doc = include_str!("docs.md")] #[derive(Default)] pub struct WebdavBuilder { - endpoint: Option, - username: Option, - password: Option, - token: Option, - root: Option, + config: WebdavConfig, http_client: Option, } impl Debug for WebdavBuilder { 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 d = f.debug_struct("WebdavBuilder"); + + d.field("config", &self.config); - de.finish() + d.finish_non_exhaustive() } } @@ -64,7 +90,7 @@ impl WebdavBuilder { /// /// 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()) @@ -78,7 +104,7 @@ impl WebdavBuilder { /// 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 } @@ -88,7 +114,7 @@ impl WebdavBuilder { /// 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 } @@ -98,14 +124,14 @@ impl WebdavBuilder { /// 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()) @@ -145,7 +171,7 @@ impl Builder for WebdavBuilder { 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") @@ -162,7 +188,7 @@ impl Builder for WebdavBuilder { // returned in the `href`. let base_dir = uri.path().trim_end_matches('/'); - 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() { @@ -175,13 +201,13 @@ impl Builder for WebdavBuilder { }; 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/webdav/mod.rs b/core/src/services/webdav/mod.rs index d8d72c449c8..f3002413717 100644 --- a/core/src/services/webdav/mod.rs +++ b/core/src/services/webdav/mod.rs @@ -17,6 +17,7 @@ mod backend; pub use backend::WebdavBuilder as Webdav; +pub use backend::WebdavConfig; mod error; mod lister;