@@ -23,6 +23,7 @@ use serde::{Deserialize, Serialize};
2323/// .with_add("/color", "silver")?
2424/// .with_move("/from", "/to")?;
2525/// # assert_eq!(patch, PatchDocument {
26+ /// # condition: None,
2627/// # operations: vec![
2728/// # PatchOperation::Add {
2829/// # path: "/color".into(),
@@ -39,10 +40,20 @@ use serde::{Deserialize, Serialize};
3940/// ```
4041#[ derive( Default , Debug , Serialize , Deserialize , PartialEq , Eq ) ]
4142pub struct PatchDocument {
43+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
44+ pub condition : Option < Cow < ' static , str > > ,
4245 pub operations : Vec < PatchOperation > ,
4346}
4447
4548impl PatchDocument {
49+ /// Adds a condition, which determines whether or not the patch should be applied.
50+ ///
51+ /// The value is an SQL-like filter predicate as a string. For example, `from c where c.taskNum = 3`.
52+ pub fn with_condition ( mut self , condition : impl Into < Cow < ' static , str > > ) -> Self {
53+ self . condition = Some ( condition. into ( ) ) ;
54+ self
55+ }
56+
4657 /// Adds a new "add" operation to the patch document.
4758 ///
4859 /// See the [type documentation](PatchDocument) for more information on patch operations.
@@ -255,6 +266,18 @@ mod tests {
255266 Ok ( ( ) )
256267 }
257268
269+ #[ test]
270+ pub fn serialize_condition ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
271+ let patch_document = PatchDocument :: default ( ) . with_condition ( "from c where c.value = 0" ) ;
272+
273+ let serialized = serde_json:: to_string ( & patch_document) . unwrap ( ) ;
274+ assert_eq ! (
275+ serialized,
276+ "{\" condition\" :\" from c where c.value = 0\" ,\" operations\" :[]}"
277+ ) ;
278+ Ok ( ( ) )
279+ }
280+
258281 #[ test]
259282 pub fn serialize_add ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
260283 let patch_document = PatchDocument :: default ( ) . with_add (
@@ -380,6 +403,30 @@ mod tests {
380403 Ok ( ( ) )
381404 }
382405
406+ #[ test]
407+ pub fn cosmos_docs_conditional_patch_example ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
408+ const TEST_DOC : & str = r#"{
409+ "condition": "from c where c.Address.ZipCode = '98101'",
410+ "operations": [
411+ {
412+ "op":"replace",
413+ "path":"/Address/ZipCode",
414+ "value":98107
415+ }
416+ ]
417+ }"# ;
418+
419+ let doc: PatchDocument = serde_json:: from_str ( TEST_DOC ) ?;
420+
421+ assert_eq ! (
422+ doc,
423+ PatchDocument :: default ( )
424+ . with_condition( "from c where c.Address.ZipCode = '98101'" )
425+ . with_replace( "/Address/ZipCode" , 98107 ) ?
426+ ) ;
427+ Ok ( ( ) )
428+ }
429+
383430 #[ test]
384431 pub fn to_json_number_f64 ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
385432 assert_eq ! (
0 commit comments