cu_ros2_bridge/
keyexpr.rs1#[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#[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 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 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}