diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index cafca6456..b355ffc60 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -93,6 +93,20 @@ typedef enum z_encoding_prefix_t { Z_ENCODING_PREFIX_IMAGE_PNG = 19, Z_ENCODING_PREFIX_IMAGE_GIF = 20, } z_encoding_prefix_t; +/** + * A :c:type:`z_keyexpr_intersection_level_t`. + * + * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** + */ +typedef enum z_keyexpr_intersection_level_t { + Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT = 0, + Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS = 1, + Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES = 2, + Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS = 3, +} z_keyexpr_intersection_level_t; /** * The priority of zenoh messages. * @@ -1643,6 +1657,14 @@ ZENOHC_API struct z_owned_keyexpr_t z_keyexpr_new(const char *name); * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type */ ZENOHC_API struct z_owned_keyexpr_t z_keyexpr_null(void); +/** + * Returns the relation between `left` and `right` from `left`'s point of view. + * + * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. + */ +ZENOHC_API +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, + struct z_keyexpr_t right); /** * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. * The user is responsible of droping the returned string using `z_drop` diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 04efe0c99..abb1914d5 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -24,6 +24,7 @@ use crate::z_str_null; use crate::GuardedTransmute; use crate::LOG_INVALID_SESSION; use libc::c_char; +use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; @@ -568,3 +569,43 @@ pub extern "C" fn z_keyexpr_join(left: z_keyexpr_t, right: z_keyexpr_t) -> z_own } } } + +/// A :c:type:`z_keyexpr_intersection_level_t`. +/// +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(C)] +pub enum z_keyexpr_intersection_level_t { + DISJOINT = 0, + INTERSECTS = 1, + INCLUDES = 2, + EQUALS = 3, +} + +impl From for z_keyexpr_intersection_level_t { + fn from(val: SetIntersectionLevel) -> Self { + match val { + SetIntersectionLevel::Disjoint => z_keyexpr_intersection_level_t::DISJOINT, + SetIntersectionLevel::Intersects => z_keyexpr_intersection_level_t::INTERSECTS, + SetIntersectionLevel::Includes => z_keyexpr_intersection_level_t::INCLUDES, + SetIntersectionLevel::Equals => z_keyexpr_intersection_level_t::EQUALS, + } + } +} + +#[no_mangle] +/// Returns the relation between `left` and `right` from `left`'s point of view. +/// +/// Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. +pub extern "C" fn z_keyexpr_relation_to( + left: z_keyexpr_t, + right: z_keyexpr_t, +) -> z_keyexpr_intersection_level_t { + match (&*left, &*right) { + (Some(l), Some(r)) => l.relation_to(r).into(), + _ => z_keyexpr_intersection_level_t::DISJOINT, + } +} diff --git a/tests/z_api_keyexpr_test.c b/tests/z_api_keyexpr_test.c index b5cdeaad1..e386e1393 100644 --- a/tests/z_api_keyexpr_test.c +++ b/tests/z_api_keyexpr_test.c @@ -73,9 +73,23 @@ void undeclare() { assert(!z_keyexpr_check(&ke)); } +void relation_to() { + z_keyexpr_t nul = z_keyexpr(NULL); + z_keyexpr_t foobar = z_keyexpr("foo/bar"); + z_keyexpr_t foostar = z_keyexpr("foo/*"); + z_keyexpr_t barstar = z_keyexpr("bar/*"); + assert(z_keyexpr_relation_to(foostar, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES); + assert(z_keyexpr_relation_to(foobar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS); + assert(z_keyexpr_relation_to(foostar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS); + assert(z_keyexpr_relation_to(barstar, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); + assert(z_keyexpr_relation_to(nul, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); + assert(z_keyexpr_relation_to(foobar, nul) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); +} + int main(int argc, char **argv) { canonize(); includes(); intersects(); undeclare(); + relation_to(); }