Skip to main content

pamoja_zenoh/
lib.rs

1#![cfg_attr(not(any(test, feature = "runtime")), no_std)]
2
3//! Zenoh key-expression logic and transport for the pamoja SDK.
4//!
5//! Zenoh addresses data by key expressions: `/`-joined chunks with a small, exact wildcard
6//! language. Before any session is opened, a node has to know whether a key is well-formed, what
7//! its one canonical spelling is, whether a subscription pattern matches a published key, and how
8//! two patterns relate. That is pure string logic with no I/O, and getting it wrong silently drops
9//! or misroutes messages, so it lives here as checked logic anchored to the Zenoh specification
10//! and tested against Zenoh's own implementation.
11//!
12//! See [`keyexpr`] for the rules and the operations:
13//!
14//! - validity: a key expression is `/`-joined non-empty chunks with no leading, trailing, or
15//!   doubled `/`, where `*` and `**` are whole-chunk wildcards and `$*` is a sub-chunk wildcard. A
16//!   chunk that starts with `@` is verbatim, and no wildcard selects it.
17//! - canonical form: two expressions that select the same keys share one spelling, so equality is
18//!   a string comparison; [`canonize`](keyexpr::canonize) produces it, and a Zenoh session accepts
19//!   nothing else. [`join`](keyexpr::join) builds a key beneath a prefix in that form.
20//! - matching: [`matches`](keyexpr::matches) tests whether a concrete key is selected by a pattern,
21//!   the routing question a subscriber asks of every publication.
22//! - relations: [`intersects`](keyexpr::intersects) tests whether two patterns share a key, and
23//!   [`includes`](keyexpr::includes) whether one covers every key of another, the questions a
24//!   router and a bridge ask of two subscriptions.
25//!
26//! With the `runtime` feature on, `ZenohTransport` adds the live half: it opens a Zenoh session
27//! and implements the core `Transport`, so Zenoh becomes the efficient
28//! edge-to-edge and fleet transport behind the same surface as every other link.
29//!
30//! # Examples
31//!
32//! ```
33//! use pamoja_zenoh::keyexpr::{canonize, includes, intersects, matches};
34//!
35//! // A subscription with a single-chunk wildcard selects a matching publication.
36//! assert!(matches("room275/*/temperature", "room275/device1/temperature"));
37//! assert!(!matches("room275/*/temperature", "room275/temperature"));
38//!
39//! // `**/*` is valid but not canonical; its one canonical spelling puts the `*` first.
40//! assert_eq!(canonize("robot/sensor/**/*").as_deref(), Some("robot/sensor/*/**"));
41//!
42//! // Two patterns overlap when some key belongs to both, and one covers the other when every
43//! // key of the second belongs to the first.
44//! assert!(intersects("room275/*/temperature", "room275/device1/**"));
45//! assert!(includes("room275/**", "room275/*/temperature"));
46//! ```
47
48extern crate alloc;
49
50pub mod keyexpr;
51
52#[cfg(feature = "runtime")]
53mod transport;
54
55#[cfg(feature = "runtime")]
56pub use transport::{Message, ZenohConfig, ZenohTransport};