use crate::err::*;
use regex::Regex;
pub(crate) const WILDCARD: &str = "*";
pub(crate) const DOUBLE_WILDCARD: &str = "**";
lazy_static! {
static ref RGX_TOPIC: Regex =
Regex::new(r"^(([a-z0-9_]+|\*|\*\*)/)*([a-z0-9_]+|\*|\*\*)$").unwrap();
}
#[test]
fn test_rgx_topic() {
assert!(RGX_TOPIC.is_match("a"));
assert!(RGX_TOPIC.is_match("abc"));
assert!(RGX_TOPIC.is_match("0"));
assert!(RGX_TOPIC.is_match("a0"));
assert!(RGX_TOPIC.is_match("0a"));
assert!(RGX_TOPIC.is_match("*"));
assert!(RGX_TOPIC.is_match("**"));
assert!(!RGX_TOPIC.is_match("a/"));
assert!(!RGX_TOPIC.is_match("0/"));
assert!(!RGX_TOPIC.is_match("*/"));
assert!(!RGX_TOPIC.is_match("**/"));
assert!(RGX_TOPIC.is_match("a/b"));
assert!(RGX_TOPIC.is_match("0/b"));
assert!(RGX_TOPIC.is_match("a/0"));
assert!(RGX_TOPIC.is_match("ab/b"));
assert!(RGX_TOPIC.is_match("a/ba"));
assert!(RGX_TOPIC.is_match("**/b"));
assert!(RGX_TOPIC.is_match("*/b"));
assert!(RGX_TOPIC.is_match("a/*"));
assert!(RGX_TOPIC.is_match("a/**"));
assert!(RGX_TOPIC.is_match("**/*"));
assert!(RGX_TOPIC.is_match("*/**"));
assert!(RGX_TOPIC.is_match("1/2"));
assert!(RGX_TOPIC.is_match("a_1/2_a_"));
assert!(RGX_TOPIC.is_match("1_/_2"));
}
pub(crate) fn parse_topic(topic_str: &str) -> BusResult<Vec<&str>> {
if !RGX_TOPIC.is_match(topic_str) {
return Err(BusError::InvalidTopicString(format!("Invalid topic string: {topic_str}")));
}
Ok(topic_str.split('/').collect::<Vec<&str>>())
}
pub fn prefix_topic(prefix: &str, topic: &str) -> String {
match topic {
"" => prefix.to_string(),
_ => format!("{prefix}/{topic}"),
}
}