use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct ModelsResponse {
#[serde(default)]
pub stt: Vec<Model>,
#[serde(default)]
pub tts: Vec<Model>,
#[serde(default)]
pub languages: HashMap<String, String>,
}
#[cfg_attr(
any(feature = "listen", feature = "read"),
doc = "It is distinct from the request-time model selector you pass when transcribing or synthesizing, [`common::options::Model`](crate::common::options::Model)."
)]
#[cfg_attr(
not(any(feature = "listen", feature = "read")),
doc = "It is distinct from the request-time model selector you pass when transcribing or synthesizing, `common::options::Model`."
)]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Model {
#[allow(missing_docs)]
pub name: Option<String>,
#[allow(missing_docs)]
pub canonical_name: Option<String>,
#[allow(missing_docs)]
pub architecture: Option<String>,
#[allow(missing_docs)]
#[serde(default)]
pub languages: Vec<String>,
#[allow(missing_docs)]
pub version: Option<String>,
#[allow(missing_docs)]
pub uuid: Option<String>,
pub batch: Option<bool>,
pub streaming: Option<bool>,
pub formatted_output: Option<bool>,
pub multilingual: Option<bool>,
pub metadata: Option<ModelMetadata>,
}
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct ModelMetadata {
#[allow(missing_docs)]
pub accent: Option<String>,
#[allow(missing_docs)]
pub age: Option<String>,
#[allow(missing_docs)]
pub color: Option<String>,
pub display_name: Option<String>,
#[allow(missing_docs)]
pub image: Option<String>,
#[allow(missing_docs)]
pub sample: Option<String>,
#[allow(missing_docs)]
#[serde(default)]
pub tags: Vec<String>,
#[allow(missing_docs)]
#[serde(default)]
pub use_cases: Vec<String>,
}
#[cfg(test)]
mod tests {
use super::ModelsResponse;
#[test]
fn deserializes_documented_response() {
let json = serde_json::json!({
"languages": {
"en": "English",
"en-US": "English (United States)",
"en-IE": "English (Ireland)"
},
"stt": [{
"name": "general",
"canonical_name": "nova-3-general",
"architecture": "nova3",
"languages": ["en", "en-US"],
"version": "2025-01-09.0",
"uuid": "bf05427e-a1f1-4ced-a976-38b2f3533d8d",
"batch": false,
"streaming": true,
"formatted_output": false,
"multilingual": false
}],
"tts": [{
"name": "angus",
"canonical_name": "aura-angus-en",
"architecture": "aura",
"languages": ["en", "en-IE"],
"version": "2024-11-19.0",
"uuid": "b50880e3-4e2e-4e53-ba27-ea0472bf2cf4",
"metadata": {
"accent": "Irish",
"display_name": "Angus",
"color": "#BA80F5",
"image": "https://static.deepgram.com/examples/avatars/angus.jpg",
"sample": "https://static.deepgram.com/examples/voices/angus.wav",
"tags": ["masculine"]
}
}]
});
let response: ModelsResponse = serde_json::from_value(json).unwrap();
assert_eq!(response.stt.len(), 1);
assert_eq!(response.tts.len(), 1);
let stt = &response.stt[0];
assert_eq!(stt.canonical_name.as_deref(), Some("nova-3-general"));
assert_eq!(stt.streaming, Some(true));
assert!(stt.metadata.is_none());
let tts = &response.tts[0];
assert_eq!(tts.name.as_deref(), Some("angus"));
assert_eq!(
tts.metadata.as_ref().unwrap().accent.as_deref(),
Some("Irish")
);
assert_eq!(
tts.metadata.as_ref().unwrap().display_name.as_deref(),
Some("Angus")
);
assert_eq!(tts.metadata.as_ref().unwrap().tags, vec!["masculine"]);
assert!(tts.batch.is_none());
assert_eq!(stt.multilingual, Some(false));
assert!(tts.multilingual.is_none());
assert_eq!(response.languages.len(), 3);
assert_eq!(
response.languages.get("en-US").map(String::as_str),
Some("English (United States)")
);
}
#[test]
fn deserializes_model_with_omitted_optional_fields() {
let json = serde_json::json!({
"stt": [{
"name": "general",
"languages": ["en"],
"streaming": true
}],
"tts": [{
"canonical_name": "aura-2-thalia-en",
"metadata": { "tags": ["feminine"], "display_name": null }
}]
});
let response: ModelsResponse = serde_json::from_value(json).unwrap();
let stt = &response.stt[0];
assert_eq!(stt.name.as_deref(), Some("general"));
assert!(stt.canonical_name.is_none());
assert!(stt.architecture.is_none());
assert!(stt.version.is_none());
assert!(stt.uuid.is_none());
assert_eq!(stt.streaming, Some(true));
let tts = &response.tts[0];
assert!(tts.name.is_none());
assert_eq!(tts.canonical_name.as_deref(), Some("aura-2-thalia-en"));
assert!(tts.uuid.is_none());
assert_eq!(tts.metadata.as_ref().unwrap().tags, vec!["feminine"]);
assert!(tts.metadata.as_ref().unwrap().display_name.is_none());
assert!(stt.multilingual.is_none());
assert!(response.languages.is_empty());
}
}