use mabi_core::tags::{parse_tag_string, Tags};
pub fn parse_port(s: &str) -> Result<u16, String> {
let port: u16 = s
.parse()
.map_err(|_| format!("'{s}' is not a valid port number"))?;
if port == 0 {
return Err("port must be between 1 and 65535 (port 0 is not allowed)".to_string());
}
Ok(port)
}
pub fn parse_nonzero_count(s: &str) -> Result<usize, String> {
let n: usize = s
.parse()
.map_err(|_| format!("'{s}' is not a valid number"))?;
if n == 0 {
return Err("value must be at least 1".to_string());
}
Ok(n)
}
#[derive(Debug, Clone)]
pub struct TagEntry {
pub key: String,
pub value: Option<String>,
}
pub fn parse_tag(s: &str) -> Result<TagEntry, String> {
let (key, value) = parse_tag_string(s)?;
Ok(TagEntry { key, value })
}
pub fn tags_from_entries(entries: &[TagEntry]) -> Tags {
let mut tags = Tags::new();
for entry in entries {
match &entry.value {
Some(v) => tags.insert(&entry.key, v),
None => tags.add_label(&entry.key),
}
}
tags
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_port_valid() {
assert_eq!(parse_port("1").unwrap(), 1);
assert_eq!(parse_port("3671").unwrap(), 3671);
assert_eq!(parse_port("65535").unwrap(), 65535);
}
#[test]
fn test_parse_port_zero_rejected() {
assert!(parse_port("0").is_err());
}
#[test]
fn test_parse_port_invalid_string() {
assert!(parse_port("abc").is_err());
assert!(parse_port("-1").is_err());
assert!(parse_port("99999").is_err());
}
#[test]
fn test_parse_nonzero_count_valid() {
assert_eq!(parse_nonzero_count("1").unwrap(), 1);
assert_eq!(parse_nonzero_count("50000").unwrap(), 50000);
}
#[test]
fn test_parse_nonzero_count_zero_rejected() {
assert!(parse_nonzero_count("0").is_err());
}
#[test]
fn test_parse_nonzero_count_invalid() {
assert!(parse_nonzero_count("abc").is_err());
assert!(parse_nonzero_count("-1").is_err());
}
#[test]
fn test_parse_tag_key_value() {
let entry = parse_tag("location=building-a").unwrap();
assert_eq!(entry.key, "location");
assert_eq!(entry.value, Some("building-a".to_string()));
}
#[test]
fn test_parse_tag_label() {
let entry = parse_tag("critical").unwrap();
assert_eq!(entry.key, "critical");
assert_eq!(entry.value, None);
}
#[test]
fn test_parse_tag_empty_value() {
let entry = parse_tag("key=").unwrap();
assert_eq!(entry.key, "key");
assert_eq!(entry.value, Some("".to_string()));
}
#[test]
fn test_parse_tag_invalid() {
assert!(parse_tag("").is_err());
assert!(parse_tag("=value").is_err());
}
#[test]
fn test_tags_from_entries() {
let entries = vec![
TagEntry {
key: "location".to_string(),
value: Some("building-a".to_string()),
},
TagEntry {
key: "floor".to_string(),
value: Some("3".to_string()),
},
TagEntry {
key: "critical".to_string(),
value: None,
},
];
let tags = tags_from_entries(&entries);
assert_eq!(tags.get("location"), Some("building-a"));
assert_eq!(tags.get("floor"), Some("3"));
assert!(tags.has_label("critical"));
}
}