This is an automated email from the ASF dual-hosted git repository. junouyang pushed a commit to branch feat/blockong-operator-range-read in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
commit e208907aca34130480f4786896027d8e419b1857 Author: owl <[email protected]> AuthorDate: Wed Aug 23 22:34:12 2023 +0800 feat(types): add stat_with API for blocking operator --- core/src/types/operator/blocking_operator.rs | 49 ++++++++++++++++++++++++--- core/src/types/operator/operator_functions.rs | 31 +++++++++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/core/src/types/operator/blocking_operator.rs b/core/src/types/operator/blocking_operator.rs index 6d4b102f2..28aa53bb6 100644 --- a/core/src/types/operator/blocking_operator.rs +++ b/core/src/types/operator/blocking_operator.rs @@ -137,12 +137,53 @@ impl BlockingOperator { /// # } /// ``` pub fn stat(&self, path: &str) -> Result<Metadata> { - let path = normalize_path(path); + self.stat_with(path).call() + } - let rp = self.inner().blocking_stat(&path, OpStat::new())?; - let meta = rp.into_metadata(); + /// Get current path's metadata **without cache** directly with extra options. + /// + /// # Notes + /// + /// Use `stat` if you: + /// + /// - Want to detect the outside changes of path. + /// - Don't want to read from cached metadata. + /// + /// You may want to use `metadata` if you are working with entries + /// returned by [`Lister`]. It's highly possible that metadata + /// you want has already been cached. + /// + /// # Examples + /// + /// ``` + /// # use anyhow::Result; + /// # use opendal::BlockingOperator; + /// use opendal::ErrorKind; + /// # + /// # #[tokio::main] + /// # async fn test(op: BlockingOperator) -> Result<()> { + /// if let Err(e) = op.stat_with("test").if_match("<etag>").call() { + /// if e.kind() == ErrorKind::NotFound { + /// println!("file not exist") + /// } + /// } + /// # Ok(()) + /// # } + /// ``` + pub fn stat_with(&self, path: &str) -> FunctionStat { + let path = normalize_path(path); - Ok(meta) + FunctionStat(OperatorFunction::new( + self.inner().clone(), + path, + OpStat::default(), + |inner, path, args| { + let rp = inner.blocking_stat(&path, args)?; + let meta = rp.into_metadata(); + + Ok(meta) + }, + )) } /// Check if this path exists or not. diff --git a/core/src/types/operator/operator_functions.rs b/core/src/types/operator/operator_functions.rs index 1000b7094..758a1cc2c 100644 --- a/core/src/types/operator/operator_functions.rs +++ b/core/src/types/operator/operator_functions.rs @@ -229,3 +229,34 @@ impl FunctionReader { self.0.call() } } + +/// Function that generated by [`BlockingOperator::stat_with`]. +/// +/// Users can add more options by public functions provided by this struct. +pub struct FunctionStat(pub(crate) OperatorFunction<OpStat, Metadata>); + +impl FunctionStat { + /// Set the If-Match for this operation. + pub fn if_match(mut self, v: &str) -> Self { + self.0 = self.0.map_args(|args| args.with_if_match(v)); + self + } + + /// Set the If-None-Match for this operation. + pub fn if_none_match(mut self, v: &str) -> Self { + self.0 = self.0.map_args(|args| args.with_if_none_match(v)); + self + } + + /// Set the version for this operation. + pub fn version(mut self, v: &str) -> Self { + self.0 = self.0.map_args(|args| args.with_version(v)); + self + } + + /// Call the function to consume all the input and generate a + /// result. + pub fn call(self) -> Result<Metadata> { + self.0.call() + } +} \ No newline at end of file
