The id of a voice, as the voice service names it. It lives in the core because a household setting names one
(the voice a character owns), and the ports' Voice speaks in one.
4use std::fmt;
6use serde::{Deserialize, Serialize};
The most characters of a voice id.
9pub const VOICE_ID_MAX: usize = 64;
The id of a voice: letters, digits, - and _, so one cannot reach a path or a query when it is put in a
request. Read from a document it is checked the same way.
Why a text is not a voice id.
21impl fmt::Display for NotAVoiceId { 22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 23 write!(f, "a voice id is 1 to {VOICE_ID_MAX} letters, digits, - or _") 24 } 25} 26 27impl std::error::Error for NotAVoiceId {} 28 29impl VoiceId { 30 pub fn new(id: &str) -> Result<Self, NotAVoiceId> { 31 let ok = !id.is_empty() && id.len() <= VOICE_ID_MAX && id.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_'); 32 if ok { Ok(Self(id.to_owned())) } else { Err(NotAVoiceId) } 33 } 34 35 pub fn as_str(&self) -> &str { 36 &self.0 37 }
Eight hex digits that stand for the id in a log: enough to tell voices apart, not the id itself (a voice id can be a private one).
51impl<'de> Deserialize<'de> for VoiceId { 52 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> { 53 let text = String::deserialize(d)?; 54 VoiceId::new(&text).map_err(serde::de::Error::custom) 55 } 56} 57 58#[cfg(test)] 59mod tests { 60 use super::*; 61 62 #[test] 63 fn an_id_is_letters_digits_dash_and_underscore() { 64 assert!(VoiceId::new("cgSgspJ2msm6clMCkdW9").is_ok()); 65 for bad in ["", "a b", "a/b", "a?b", &"x".repeat(VOICE_ID_MAX + 1)] { 66 assert_eq!(VoiceId::new(bad), Err(NotAVoiceId), "{bad:?}"); 67 } 68 assert!(serde_json::from_str::<VoiceId>("\"a b\"").is_err(), "a document is checked too"); 69 } 70 71 #[test] 72 fn the_tag_tells_voices_apart_without_being_the_id() { 73 let (a, b) = (VoiceId::new("one").unwrap(), VoiceId::new("two").unwrap()); 74 assert_ne!(a.tag(), b.tag()); 75 assert!(!a.tag().contains("one")); 76 } 77}