use crate::{Error, Result};
pub fn validate_chat_speaker_id(id: impl AsRef<str>) -> Result<()> {
let id = id.as_ref();
if id.is_empty() {
return Err(Error::InvalidInput("chat id must not be empty".into()));
}
if id.contains('\r') || id.contains('\n') {
return Err(Error::InvalidInput(
"chat id must not contain line breaks".into(),
));
}
if id.contains(':') {
return Err(Error::InvalidInput("chat id must not contain ':'".into()));
}
Ok(())
}
pub(crate) fn escape_chat_heading_label(id: &str) -> String {
let mut s = String::with_capacity(id.len());
for ch in id.chars() {
if matches!(ch, '\\' | '#') {
s.push('\\');
}
s.push(ch);
}
s
}
pub fn validate_entity_name(name: impl AsRef<str>) -> Result<()> {
let name = name.as_ref();
if name.is_empty() {
return Err(Error::InvalidInput("name must not be empty".into()));
}
if name == "." || name == ".." {
return Err(Error::InvalidInput("name must not be '.' or '..'".into()));
}
if name.contains('/') {
return Err(Error::InvalidInput("name must not contain '/'".into()));
}
if name.contains('\\') {
return Err(Error::InvalidInput("name must not contain '\\'".into()));
}
if name.chars().all(|c| c.is_ascii_digit()) {
return Err(Error::InvalidInput(
"name must not be a pure decimal number".into(),
));
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::{escape_chat_heading_label, validate_chat_speaker_id, validate_entity_name};
#[test]
fn chat_id_rejects_empty_colon_and_newlines() {
assert!(validate_chat_speaker_id("").is_err());
assert!(validate_chat_speaker_id("a:b").is_err());
assert!(validate_chat_speaker_id("a\nb").is_err());
assert!(validate_chat_speaker_id("ok").is_ok());
}
#[test]
fn escape_chat_heading_escapes_hash_and_backslash() {
assert_eq!(escape_chat_heading_label("a"), "a");
assert_eq!(escape_chat_heading_label("a#b"), "a\\#b");
assert_eq!(escape_chat_heading_label("a\\b"), "a\\\\b");
}
#[test]
fn entity_name_rejects_dot_segments_and_separators() {
assert!(validate_entity_name(".").is_err());
assert!(validate_entity_name("..").is_err());
assert!(validate_entity_name("a/b").is_err());
assert!(validate_entity_name(r"a\b").is_err());
assert!(validate_entity_name("42").is_err());
assert!(validate_entity_name("ok").is_ok());
}
}