Skip to main content

zenkey_fleet/
session.rs

1//! Session setup for un-namespaced observers (RFC 09 §5).
2
3use anyhow::{Context, Result};
4use zenoh::Session;
5
6/// Open a session for a read-only explorer.
7///
8/// RFC 09 §5: debug tools run *without* the session namespace and spell full
9/// keys — "which is also the honest view of what is on the wire". So we never
10/// set `namespace`, and every key this tool prints is the real one.
11///
12/// Scouting defaults to **off**. A bus explorer that multicast-scouts will join
13/// whatever mesh it can find, which is how a throwaway session ends up
14/// contaminating a live fleet; opt in explicitly with `--scouting` when you
15/// mean it.
16pub async fn open(connect: &[String], listen: &[String], scouting: bool) -> Result<Session> {
17    let mut config = zenoh::Config::default();
18    let json_list = |v: &[String]| {
19        let items: Vec<String> = v.iter().map(|e| format!("{e:?}")).collect();
20        format!("[{}]", items.join(","))
21    };
22    config
23        .insert_json5("scouting/multicast/enabled", &scouting.to_string())
24        .ok();
25    if !connect.is_empty() {
26        config
27            .insert_json5("connect/endpoints", &json_list(connect))
28            .ok();
29    }
30    if !listen.is_empty() {
31        config
32            .insert_json5("listen/endpoints", &json_list(listen))
33            .ok();
34    }
35    zenoh::open(config)
36        .await
37        .map_err(|e| anyhow::anyhow!("{e}"))
38        .context("failed to open Zenoh session")
39}