diff --git a/core/src/services/fs/backend.rs b/core/src/services/fs/backend.rs index 89f2c1ca683..9c8d5b911f8 100644 --- a/core/src/services/fs/backend.rs +++ b/core/src/services/fs/backend.rs @@ -23,30 +23,41 @@ use std::sync::Arc; use chrono::DateTime; use log::debug; +use serde::Deserialize; + +use crate::raw::*; +use crate::*; use super::core::*; use super::lister::FsLister; use super::reader::FsReader; use super::writer::FsWriter; -use crate::raw::*; -use crate::*; + +/// config for file system +#[derive(Default, Deserialize, Debug)] +#[serde(default)] +#[non_exhaustive] +pub struct FsConfig { + /// root dir for backend + pub root: Option, + + /// tmp dir for atomic write + pub atomic_write_dir: Option, +} /// POSIX file system support. #[doc = include_str!("docs.md")] #[derive(Default, Debug)] pub struct FsBuilder { - root: Option, - atomic_write_dir: Option, + config: FsConfig, } impl FsBuilder { /// Set root for backend. pub fn root(&mut self, root: &str) -> &mut Self { - self.root = if root.is_empty() { - None - } else { - Some(PathBuf::from(root)) - }; + if !root.is_empty() { + self.config.root = Some(root.to_string()); + } self } @@ -58,11 +69,9 @@ impl FsBuilder { /// - When append is enabled, we will not use atomic write /// to avoid data loss and performance issue. pub fn atomic_write_dir(&mut self, dir: &str) -> &mut Self { - self.atomic_write_dir = if dir.is_empty() { - None - } else { - Some(PathBuf::from(dir)) - }; + if !dir.is_empty() { + self.config.atomic_write_dir = Some(dir.to_string()); + } self } @@ -73,19 +82,15 @@ impl Builder for FsBuilder { type Accessor = FsBackend; fn from_map(map: HashMap) -> Self { - let mut builder = FsBuilder::default(); - - map.get("root").map(|v| builder.root(v)); - map.get("atomic_write_dir") - .map(|v| builder.atomic_write_dir(v)); - - builder + let config = FsConfig::deserialize(ConfigDeserializer::new(map)) + .expect("config deserialize must succeed"); + FsBuilder { config } } fn build(&mut self) -> Result { debug!("backend build started: {:?}", &self); - let root = match self.root.take() { + let root = match self.config.root.take().map(PathBuf::from) { Some(root) => Ok(root), None => Err(Error::new( ErrorKind::ConfigInvalid, @@ -106,7 +111,7 @@ impl Builder for FsBuilder { } } - let atomic_write_dir = self.atomic_write_dir.take(); + let atomic_write_dir = self.config.atomic_write_dir.take().map(PathBuf::from); // If atomic write dir is not exist, we must create it. if let Some(d) = &atomic_write_dir { @@ -240,9 +245,9 @@ impl Access for FsBackend { /// /// There are three ways to get the total file length: /// - /// - call std::fs::metadata directly and than open. (400ns) - /// - open file first, and than use `f.metadata()` (300ns) - /// - open file first, and than use `seek`. (100ns) + /// - call std::fs::metadata directly and then open. (400ns) + /// - open file first, and then use `f.metadata()` (300ns) + /// - open file first, and then use `seek`. (100ns) /// /// Benchmark could be found [here](https://gist.github.com/Xuanwo/48f9cfbc3022ea5f865388bb62e1a70f) async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> { diff --git a/core/src/services/fs/mod.rs b/core/src/services/fs/mod.rs index a597690c197..6ffe4896a86 100644 --- a/core/src/services/fs/mod.rs +++ b/core/src/services/fs/mod.rs @@ -17,6 +17,7 @@ mod backend; pub use backend::FsBuilder as Fs; +pub use backend::FsConfig; mod core; mod lister; diff --git a/core/src/services/mod.rs b/core/src/services/mod.rs index 65d9bf30fcd..f6e7c159313 100644 --- a/core/src/services/mod.rs +++ b/core/src/services/mod.rs @@ -64,6 +64,8 @@ pub use self::etcd::EtcdConfig; mod fs; #[cfg(feature = "services-fs")] pub use fs::Fs; +#[cfg(feature = "services-fs")] +pub use fs::FsConfig; #[cfg(feature = "services-ftp")] mod ftp;