Skip to main content

cu_ros2_bridge/
keyexpr.rs

1#[macro_export]
2macro_rules! format_keyexpr_raw {
3    ($first:expr, $($arg:expr),*) => {{
4        use $crate::error::cu_error_map;
5
6        let mut result = KeyExpr::new($first.to_string());
7        $(
8            if let Ok(r) = result {
9              result = r.join(&$arg.to_string());
10            }
11        )*
12        result.map_err(cu_error_map("Bad keyexpr argument"))
13    }};
14}
15
16#[macro_export]
17macro_rules! format_keyexpr {
18    ($first:expr, $($arg:expr),*) => {{
19
20        use $crate::keyexpr::normalize_chunk;
21        $crate::format_keyexpr_raw!(normalize_chunk($first), $(normalize_chunk($arg)), *)
22    }};
23}
24
25/// Liveliness keyexpr mangles key parts in order to escape slashes
26#[macro_export]
27macro_rules! format_liveliness_keyexpr {
28    ($first:expr, $($arg:expr),*) => {{
29
30        use $crate::keyexpr::mangle_chunk;
31        $crate::format_keyexpr_raw!(mangle_chunk($first), $(mangle_chunk($arg)), *)
32    }};
33}
34
35pub(crate) fn normalize_chunk<T>(arg: T) -> String
36where
37    T: ToString,
38{
39    let str = arg.to_string();
40    let str_trimmed = str.trim_matches('/');
41    // Empty chunks are forbidden
42    if str_trimmed.is_empty() {
43        return "_".into();
44    }
45
46    str_trimmed.into()
47}
48
49pub(crate) fn mangle_chunk<T>(arg: T) -> String
50where
51    T: ToString,
52{
53    let str = arg.to_string();
54    // Empty chunks are forbidden
55    if str.is_empty() {
56        return "%".into();
57    }
58
59    str.replace("/", "%")
60}
61
62#[cfg(test)]
63mod tests {
64    use zenoh::key_expr::KeyExpr;
65
66    #[test]
67    fn test_basic_keyexpr() {
68        {
69            let keyexpr = format_keyexpr!("test", "copper").unwrap();
70            assert_eq!(keyexpr.to_string(), "test/copper")
71        }
72        {
73            let keyexpr = format_liveliness_keyexpr!("test", "copper").unwrap();
74            assert_eq!(keyexpr.to_string(), "test/copper")
75        }
76    }
77
78    #[test]
79    fn test_special_keyexpr() {
80        {
81            let keyexpr = format_keyexpr!("@prefix", "/topic/a/", 1).unwrap();
82            assert_eq!(keyexpr.to_string(), "@prefix/topic/a/1")
83        }
84
85        {
86            let keyexpr = format_liveliness_keyexpr!("@prefix", "", "/topic/a", 1).unwrap();
87            assert_eq!(keyexpr.to_string(), "@prefix/%/%topic%a/1")
88        }
89    }
90}