diff --git a/core/src/services/mod.rs b/core/src/services/mod.rs index f67d2a23349c..d0e2d9903268 100644 --- a/core/src/services/mod.rs +++ b/core/src/services/mod.rs @@ -216,6 +216,8 @@ mod webhdfs; mod onedrive; #[cfg(feature = "services-onedrive")] pub use onedrive::Onedrive; +#[cfg(feature = "services-onedrive")] +pub use onedrive::OnedriveConfig; #[cfg(feature = "services-gdrive")] mod gdrive; diff --git a/core/src/services/onedrive/builder.rs b/core/src/services/onedrive/builder.rs index 96aa426e8fd4..bd98985ae875 100644 --- a/core/src/services/onedrive/builder.rs +++ b/core/src/services/onedrive/builder.rs @@ -20,25 +20,47 @@ use std::fmt::Debug; use std::fmt::Formatter; use log::debug; +use serde::Deserialize; use super::backend::OnedriveBackend; use crate::raw::normalize_root; +use crate::raw::ConfigDeserializer; use crate::raw::HttpClient; use crate::Scheme; use crate::*; +/// Config for [OneDrive](https://onedrive.com) backend support. +#[derive(Default, Deserialize)] +#[serde(default)] +#[non_exhaustive] +pub struct OnedriveConfig { + /// bearer access token for OneDrive + pub access_token: Option, + /// root path of OneDrive folder. + pub root: Option, +} + +impl Debug for OnedriveConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("OnedriveConfig") + .field("root", &self.root) + .finish_non_exhaustive() + } +} + /// [OneDrive](https://onedrive.com) backend support. #[doc = include_str!("docs.md")] #[derive(Default)] pub struct OnedriveBuilder { - access_token: Option, - root: Option, + config: OnedriveConfig, http_client: Option, } impl Debug for OnedriveBuilder { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Backend").field("root", &self.root).finish() + f.debug_struct("Backend") + .field("config", &self.config) + .finish() } } @@ -47,13 +69,13 @@ impl OnedriveBuilder { /// /// default: no access token, which leads to failure pub fn access_token(&mut self, access_token: &str) -> &mut Self { - self.access_token = Some(access_token.to_string()); + self.config.access_token = Some(access_token.to_string()); self } /// Set root path of OneDrive folder. pub fn root(&mut self, root: &str) -> &mut Self { - self.root = Some(root.to_string()); + self.config.root = Some(root.to_string()); self } @@ -75,16 +97,19 @@ impl Builder for OnedriveBuilder { type Accessor = OnedriveBackend; fn from_map(map: HashMap) -> Self { - let mut builder = Self::default(); - - map.get("root").map(|v| builder.root(v)); - map.get("access_token").map(|v| builder.access_token(v)); - - builder + // Deserialize the configuration from the HashMap. + let config = OnedriveConfig::deserialize(ConfigDeserializer::new(map)) + .expect("config deserialize must succeed"); + + // Create an OnedriveBuilder instance with the deserialized config. + OnedriveBuilder { + config, + http_client: None, + } } fn build(&mut self) -> Result { - 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() { @@ -96,7 +121,7 @@ impl Builder for OnedriveBuilder { })? }; - match self.access_token.clone() { + match self.config.access_token.clone() { Some(access_token) => Ok(OnedriveBackend::new(root, access_token, client)), None => Err(Error::new(ErrorKind::ConfigInvalid, "access_token not set")), } diff --git a/core/src/services/onedrive/mod.rs b/core/src/services/onedrive/mod.rs index 359f1d84ef9f..672fb6c7e1e7 100644 --- a/core/src/services/onedrive/mod.rs +++ b/core/src/services/onedrive/mod.rs @@ -21,5 +21,7 @@ mod error; mod graph_model; pub use builder::OnedriveBuilder as Onedrive; +pub use builder::OnedriveConfig; + mod lister; mod writer;