pub fn parse_capabilities(extra: &str) -> Vec<String> {
if let Some(idx) = extra.find("::") {
let right = extra[idx + 2..].trim();
if right.is_empty() {
return Vec::new();
}
return right.split_whitespace().map(|s| s.to_owned()).collect();
}
let tokens: Vec<String> = extra
.split_whitespace()
.filter(|t| t.contains(':'))
.map(|s| s.to_owned())
.collect();
tokens
}
pub fn supports_v4(capabilities: &[String]) -> bool {
capabilities.iter().any(|c| c == "SLPROTO:4.0")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_with_v4() {
let caps = parse_capabilities("(2020.075) :: SLPROTO:4.0 SLPROTO:3.1");
assert_eq!(caps, vec!["SLPROTO:4.0", "SLPROTO:3.1"]);
assert!(supports_v4(&caps));
}
#[test]
fn parse_without_v4() {
let caps = parse_capabilities("(2020.075) :: SLPROTO:3.1");
assert_eq!(caps, vec!["SLPROTO:3.1"]);
assert!(!supports_v4(&caps));
}
#[test]
fn parse_empty_extra() {
let caps = parse_capabilities("");
assert!(caps.is_empty());
assert!(!supports_v4(&caps));
}
#[test]
fn parse_no_separator_no_caps() {
let caps = parse_capabilities("(2020.075)");
assert!(caps.is_empty());
}
#[test]
fn parse_no_separator_with_caps() {
let caps = parse_capabilities("SLPROTO:4.0 SLPROTO:3.1");
assert_eq!(caps, vec!["SLPROTO:4.0", "SLPROTO:3.1"]);
assert!(supports_v4(&caps));
}
#[test]
fn parse_separator_but_empty_right() {
let caps = parse_capabilities("(2020.075) :: ");
assert!(caps.is_empty());
}
#[test]
fn parse_multiple_capabilities() {
let caps = parse_capabilities(":: SLPROTO:4.0 CAP:AUTH CAP:WINDOW");
assert_eq!(caps, vec!["SLPROTO:4.0", "CAP:AUTH", "CAP:WINDOW"]);
assert!(supports_v4(&caps));
}
#[test]
fn supports_v4_empty() {
assert!(!supports_v4(&[]));
}
}