diff --git a/core/src/raw/ops.rs b/core/src/raw/ops.rs index a51b0b144e02..5875160b068f 100644 --- a/core/src/raw/ops.rs +++ b/core/src/raw/ops.rs @@ -601,7 +601,7 @@ pub struct OpWrite { cache_control: Option, executor: Option, if_none_match: Option, - if_not_exist: Option, + if_not_exists: bool, user_metadata: Option>, } @@ -699,14 +699,14 @@ impl OpWrite { } /// Set the If-Not-Exist of the option - pub fn with_if_not_exist(mut self, b: bool) -> Self { - self.if_not_exist = Some(b); + pub fn with_if_not_exists(mut self, b: bool) -> Self { + self.if_not_exists = b; self } /// Get If-Not-Exist from option - pub fn if_not_exist(&self) -> Option { - self.if_not_exist + pub fn if_not_exists(&self) -> bool { + self.if_not_exists } /// Merge given executor into option. diff --git a/core/src/services/s3/core.rs b/core/src/services/s3/core.rs index 99cf3090e40f..abc97c4453d8 100644 --- a/core/src/services/s3/core.rs +++ b/core/src/services/s3/core.rs @@ -480,10 +480,8 @@ impl S3Core { req = req.header(IF_NONE_MATCH, if_none_match); } - if let Some(if_not_exist) = args.if_not_exist() { - if if_not_exist { - req = req.header(IF_NONE_MATCH, "*"); - } + if args.if_not_exists() { + req = req.header(IF_NONE_MATCH, "*"); } // Set body diff --git a/core/src/types/operator/operator.rs b/core/src/types/operator/operator.rs index 6a76ccdf77f1..11cc67861cbf 100644 --- a/core/src/types/operator/operator.rs +++ b/core/src/types/operator/operator.rs @@ -1254,20 +1254,22 @@ impl Operator { /// # } /// ``` /// - /// ## `if_not_exist` + /// ## `if_not_exists` /// - /// Set `if_not_exist` for this `write` request. This can be treated as a simplified version - /// of [`OpWrite::if_none_match`]. + /// This feature allows to safely write a file only if it does not exist. It is designed + /// to be concurrency-safe, and can be used to a file lock. For storage services that + /// support the `if_not_exist` feature, only one write operation will succeed, while all + /// other attempts will fail. /// - /// This feature is used to write a file only when it doesn't exist. If the file already - /// exists, an error with kind [`ErrorKind::ConditionNotMatch`] will be returned. + /// If the file already exists, an error with kind [`ErrorKind::ConditionNotMatch`] will + /// be returned. /// /// ```no_run /// # use opendal::{ErrorKind, Result}; /// use opendal::Operator; /// # async fn test(op: Operator, etag: &str) -> Result<()> { /// let bs = b"hello, world!".to_vec(); - /// let res = op.write_with("path/to/file", bs).if_not_exist(true).await; + /// let res = op.write_with("path/to/file", bs).if_not_exists(true).await; /// assert!(res.is_err()); /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ConditionNotMatch); /// # Ok(())} diff --git a/core/src/types/operator/operator_futures.rs b/core/src/types/operator/operator_futures.rs index f1652bf191fb..17f1cb77c749 100644 --- a/core/src/types/operator/operator_futures.rs +++ b/core/src/types/operator/operator_futures.rs @@ -330,8 +330,8 @@ impl>> FutureWrite { } /// Set the If-Not-Exist for this operation. - pub fn if_not_exist(self, b: bool) -> Self { - self.map(|(args, options, bs)| (args.with_if_not_exist(b), options, bs)) + pub fn if_not_exists(self, b: bool) -> Self { + self.map(|(args, options, bs)| (args.with_if_not_exists(b), options, bs)) } /// Set the user defined metadata of the op diff --git a/core/tests/behavior/async_write.rs b/core/tests/behavior/async_write.rs index e96cb166eeb7..044de888f8d6 100644 --- a/core/tests/behavior/async_write.rs +++ b/core/tests/behavior/async_write.rs @@ -45,7 +45,7 @@ pub fn tests(op: &Operator, tests: &mut Vec) { test_write_with_content_type, test_write_with_content_disposition, test_write_with_if_none_match, - test_write_with_if_not_exist, + test_write_with_if_not_exists, test_write_with_user_metadata, test_writer_write, test_writer_write_with_overwrite, @@ -648,8 +648,8 @@ pub async fn test_write_with_if_none_match(op: Operator) -> Result<()> { Ok(()) } -/// Write an file with if_not_exist will get a ConditionNotMatch error if file exists. -pub async fn test_write_with_if_not_exist(op: Operator) -> Result<()> { +/// Write an file with if_not_exists will get a ConditionNotMatch error if file exists. +pub async fn test_write_with_if_not_exists(op: Operator) -> Result<()> { if !op.info().full_capability().write_with_if_not_exist { return Ok(()); } @@ -661,7 +661,7 @@ pub async fn test_write_with_if_not_exist(op: Operator) -> Result<()> { .expect("write must succeed"); let res = op .write_with(&path, content.clone()) - .if_not_exist(true) + .if_not_exists(true) .await; assert!(res.is_err()); assert_eq!(res.unwrap_err().kind(), ErrorKind::ConditionNotMatch);