Skip to main content

zai_rs/model/voice_list/
request.rs

1use serde::{Deserialize, Serialize};
2use validator::Validate;
3
4/// Query parameters for listing voices.
5#[derive(Debug, Clone, Serialize, Validate)]
6#[validate(schema(function = "validate_voice_list_query"))]
7pub struct VoiceListQuery {
8    /// Voice-name filter. Pass the unescaped value; the client percent-encodes
9    /// query parameters.
10    #[serde(skip_serializing_if = "Option::is_none")]
11    #[validate(length(min = 1))]
12    pub voice_name: Option<String>,
13    /// Voice origin (`OFFICIAL` or `PRIVATE` on the wire).
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub voice_type: Option<VoiceType>,
16}
17
18fn validate_voice_list_query(query: &VoiceListQuery) -> Result<(), validator::ValidationError> {
19    if query
20        .voice_name
21        .as_deref()
22        .is_some_and(|name| name.trim().is_empty())
23    {
24        Err(validator::ValidationError::new(
25            "voice_name_must_not_be_blank",
26        ))
27    } else {
28        Ok(())
29    }
30}
31
32impl Default for VoiceListQuery {
33    fn default() -> Self {
34        Self::new()
35    }
36}
37
38impl VoiceListQuery {
39    /// Create a new empty voice-list query.
40    pub fn new() -> Self {
41        Self {
42            voice_name: None,
43            voice_type: None,
44        }
45    }
46    /// Filter by voice name.
47    pub fn with_voice_name(mut self, name: impl Into<String>) -> Self {
48        self.voice_name = Some(name.into());
49        self
50    }
51    /// Filter by voice type (official / private).
52    pub fn with_voice_type(mut self, vt: VoiceType) -> Self {
53        self.voice_type = Some(vt);
54        self
55    }
56}
57
58/// Voice origin: official preset or user-cloned private voice.
59#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
60#[serde(rename_all = "UPPERCASE")]
61pub enum VoiceType {
62    /// Official preset voice.
63    Official,
64    /// User-cloned private voice.
65    Private,
66}
67
68impl VoiceType {
69    /// Return the canonical upstream string (`"OFFICIAL"` / `"PRIVATE"`).
70    pub fn as_str(&self) -> &'static str {
71        match self {
72            VoiceType::Official => "OFFICIAL",
73            VoiceType::Private => "PRIVATE",
74        }
75    }
76}