From 66b80d411aa78f22e467b8405de2e57378b17b6f Mon Sep 17 00:00:00 2001 From: ilgmi Date: Wed, 29 Jan 2025 19:30:10 +0100 Subject: [PATCH 1/3] add the parameter output for find_path. Necessary to get rpc output fields for example in sysrepo --- src/data.rs | 10 ++++++---- tests/data.rs | 23 +++++++++++------------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/data.rs b/src/data.rs index b04f23d..778b18c 100644 --- a/src/data.rs +++ b/src/data.rs @@ -264,17 +264,19 @@ pub trait Data<'a> { } /// Search in the given data for a single node matching the provided XPath. + /// Whether to search in RPC/action output nodes or in input nodes. /// /// The expected format of the expression is JSON, meaning the first node in /// every path must have its module name as prefix or be the special `*` /// value for all the nodes. - fn find_path(&'a self, path: &str) -> Result> { + fn find_path(&'a self, path: &str, output: bool) -> Result> { let path = CString::new(path).unwrap(); let mut rnode = std::ptr::null_mut(); let rnode_ptr = &mut rnode; + let output = if output { 1u8 } else { 0u8 }; let ret = unsafe { - ffi::lyd_find_path(self.raw(), path.as_ptr(), 0u8, rnode_ptr) + ffi::lyd_find_path(self.raw(), path.as_ptr(), output, rnode_ptr) }; if ret != ffi::LY_ERR::LY_SUCCESS { return Err(Error::new(self.context())); @@ -752,7 +754,7 @@ impl<'a> DataTree<'a> { /// Remove a data node. pub fn remove(&mut self, path: &str) -> Result<()> { - let dnode = self.find_path(path)?; + let dnode = self.find_path(path, false)?; unsafe { ffi::lyd_free_tree(dnode.raw) }; Ok(()) } @@ -988,7 +990,7 @@ impl<'a> DataTreeOwningRef<'a> { let raw = { match tree.new_path(path, value, output)? { Some(node) => node.raw, - None => tree.find_path(path)?.raw, + None => tree.find_path(path, output)?.raw, } }; Ok(unsafe { DataTreeOwningRef::from_raw(tree, raw) }) diff --git a/tests/data.rs b/tests/data.rs index 0114b52..a90d869 100644 --- a/tests/data.rs +++ b/tests/data.rs @@ -207,6 +207,7 @@ fn create_context() -> Context { "ietf-ip", "ietf-routing", "ietf-isis", + "ietf-mpls-ldp" ] { ctx.load_module(module_name, None, &[]) .expect("Failed to load module"); @@ -307,10 +308,10 @@ fn data_find_path() { let dtree1 = parse_json_data(&ctx, JSON_TREE1); assert!(dtree1 - .find_path("/ietf-interfaces:interfaces/interface") + .find_path("/ietf-interfaces:interfaces/interface", false) .is_err()); assert!(dtree1 - .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']") + .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']", false) .is_ok()); } @@ -387,7 +388,7 @@ fn data_duplicate_subtree() { let dtree1 = parse_json_data(&ctx, JSON_TREE1); let dnode = dtree1 - .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']") + .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']", false) .expect("Failed to lookup data"); // Duplicate without parents. @@ -671,8 +672,7 @@ fn data_iterator_ancestors() { assert_eq!( dtree1 .find_path( - "/ietf-interfaces:interfaces/interface[name='eth/0/0']/type", - ) + "/ietf-interfaces:interfaces/interface[name='eth/0/0']/type", false) .expect("Failed to lookup data") .ancestors() .map(|dnode| dnode.path()) @@ -685,8 +685,7 @@ fn data_iterator_ancestors() { assert_eq!( dtree1 .find_path( - "/ietf-interfaces:interfaces/interface[name='eth/0/0']/type", - ) + "/ietf-interfaces:interfaces/interface[name='eth/0/0']/type", false) .expect("Failed to lookup data") .inclusive_ancestors() .map(|dnode| dnode.path()) @@ -706,7 +705,7 @@ fn data_iterator_siblings() { assert_eq!( dtree1 - .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']") + .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']", false) .expect("Failed to lookup data") .siblings() .map(|dnode| dnode.path()) @@ -715,7 +714,7 @@ fn data_iterator_siblings() { ); assert_eq!( dtree1 - .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']") + .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']", false) .expect("Failed to lookup data") .inclusive_siblings() .map(|dnode| dnode.path()) @@ -734,7 +733,7 @@ fn data_iterator_children() { assert_eq!( dtree1 - .find_path("/ietf-interfaces:interfaces") + .find_path("/ietf-interfaces:interfaces", false) .expect("Failed to lookup data") .children() .map(|dnode| dnode.path()) @@ -754,7 +753,7 @@ fn data_is_default() { assert_eq!( dtree2 .find_path( - "/ietf-interfaces:interfaces/interface[name='eth/0/0']/enabled" + "/ietf-interfaces:interfaces/interface[name='eth/0/0']/enabled", false ) .expect("Failed to lookup data") .is_default(), @@ -763,7 +762,7 @@ fn data_is_default() { assert_eq!( dtree2 .find_path( - "/ietf-interfaces:interfaces/interface[name='eth/0/2']/enabled" + "/ietf-interfaces:interfaces/interface[name='eth/0/2']/enabled", false ) .expect("Failed to lookup data") .is_default(), From adc106ac652a0eb73ccc4f2c0aca46afcc5b7fb6 Mon Sep 17 00:00:00 2001 From: ilgmi Date: Thu, 30 Jan 2025 08:07:47 +0100 Subject: [PATCH 2/3] run rustfmt --- tests/data.rs | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/tests/data.rs b/tests/data.rs index a90d869..d3fa608 100644 --- a/tests/data.rs +++ b/tests/data.rs @@ -207,7 +207,7 @@ fn create_context() -> Context { "ietf-ip", "ietf-routing", "ietf-isis", - "ietf-mpls-ldp" + "ietf-mpls-ldp", ] { ctx.load_module(module_name, None, &[]) .expect("Failed to load module"); @@ -311,7 +311,10 @@ fn data_find_path() { .find_path("/ietf-interfaces:interfaces/interface", false) .is_err()); assert!(dtree1 - .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']", false) + .find_path( + "/ietf-interfaces:interfaces/interface[name='eth/0/0']", + false + ) .is_ok()); } @@ -388,7 +391,10 @@ fn data_duplicate_subtree() { let dtree1 = parse_json_data(&ctx, JSON_TREE1); let dnode = dtree1 - .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']", false) + .find_path( + "/ietf-interfaces:interfaces/interface[name='eth/0/0']", + false, + ) .expect("Failed to lookup data"); // Duplicate without parents. @@ -672,7 +678,9 @@ fn data_iterator_ancestors() { assert_eq!( dtree1 .find_path( - "/ietf-interfaces:interfaces/interface[name='eth/0/0']/type", false) + "/ietf-interfaces:interfaces/interface[name='eth/0/0']/type", + false + ) .expect("Failed to lookup data") .ancestors() .map(|dnode| dnode.path()) @@ -685,7 +693,9 @@ fn data_iterator_ancestors() { assert_eq!( dtree1 .find_path( - "/ietf-interfaces:interfaces/interface[name='eth/0/0']/type", false) + "/ietf-interfaces:interfaces/interface[name='eth/0/0']/type", + false + ) .expect("Failed to lookup data") .inclusive_ancestors() .map(|dnode| dnode.path()) @@ -705,7 +715,10 @@ fn data_iterator_siblings() { assert_eq!( dtree1 - .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']", false) + .find_path( + "/ietf-interfaces:interfaces/interface[name='eth/0/0']", + false + ) .expect("Failed to lookup data") .siblings() .map(|dnode| dnode.path()) @@ -714,7 +727,10 @@ fn data_iterator_siblings() { ); assert_eq!( dtree1 - .find_path("/ietf-interfaces:interfaces/interface[name='eth/0/0']", false) + .find_path( + "/ietf-interfaces:interfaces/interface[name='eth/0/0']", + false + ) .expect("Failed to lookup data") .inclusive_siblings() .map(|dnode| dnode.path()) @@ -753,7 +769,8 @@ fn data_is_default() { assert_eq!( dtree2 .find_path( - "/ietf-interfaces:interfaces/interface[name='eth/0/0']/enabled", false + "/ietf-interfaces:interfaces/interface[name='eth/0/0']/enabled", + false ) .expect("Failed to lookup data") .is_default(), @@ -762,7 +779,8 @@ fn data_is_default() { assert_eq!( dtree2 .find_path( - "/ietf-interfaces:interfaces/interface[name='eth/0/2']/enabled", false + "/ietf-interfaces:interfaces/interface[name='eth/0/2']/enabled", + false ) .expect("Failed to lookup data") .is_default(), From 0767ad943b837d4167709975a4097d4bc28dc2ef Mon Sep 17 00:00:00 2001 From: ilgmi Date: Thu, 30 Jan 2025 08:09:14 +0100 Subject: [PATCH 3/3] run rustfmt --- src/data.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/data.rs b/src/data.rs index 778b18c..43d0119 100644 --- a/src/data.rs +++ b/src/data.rs @@ -269,7 +269,11 @@ pub trait Data<'a> { /// The expected format of the expression is JSON, meaning the first node in /// every path must have its module name as prefix or be the special `*` /// value for all the nodes. - fn find_path(&'a self, path: &str, output: bool) -> Result> { + fn find_path( + &'a self, + path: &str, + output: bool, + ) -> Result> { let path = CString::new(path).unwrap(); let mut rnode = std::ptr::null_mut(); let rnode_ptr = &mut rnode;