darkwing/server/services/browser_profile_services/config/
voices.rsuse crate::{
database::browser_profile::Platform,
server::{
dtos::{
browser_profile_dto::BrowserProfileFullData, start_dto::StartRequest,
},
error::Error,
},
};
use serde::{Deserialize, Serialize};
use super::{
consts::{MACOS_VOICES, WINDOWS_VOICES},
screen::Screen,
FromStartRequest, Navigator,
};
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct Voice {
#[serde(rename = "lang")]
pub(super) language: String,
pub(super) name: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct Voices(pub Vec<Voice>);
impl FromStartRequest<Voices> for Voices {
fn from_start_request(
bp: &BrowserProfileFullData,
_request: &StartRequest,
navigator: &Navigator,
_screen: &Screen,
_token: &str,
) -> Result<Self, Error> {
let locale = navigator.locale.clone();
let voices = match bp.platform {
Platform::Windows => WINDOWS_VOICES
.iter()
.copied()
.filter(|voice| {
voice.0.to_lowercase() == locale.clone().to_lowercase() || voice.0.to_lowercase() == "en-US".to_string().to_lowercase()
})
.collect(),
Platform::Macos => MACOS_VOICES
.iter()
.copied()
.filter(|voice| {
voice.0.to_lowercase() != locale.clone().to_lowercase() || voice.0.to_lowercase() == "en-US".to_string().to_lowercase()
|| voice.0.to_lowercase() == "en".to_string().to_lowercase()
})
.collect(),
Platform::Linux => Vec::new(),
};
let voices = voices
.into_iter()
.map(|voice| Voice {
language: voice.0.to_string(),
name: voice.1.to_string(),
})
.collect();
Ok(Self(voices))
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct SpeechVoices {
pub(super) enabled: bool,
pub(super) voices: Voices,
}
impl FromStartRequest<SpeechVoices> for SpeechVoices {
fn from_start_request(
bp: &BrowserProfileFullData,
request: &StartRequest,
navigator: &Navigator,
screen: &Screen,
token: &str,
) -> Result<Self, Error> {
Ok(SpeechVoices {
enabled: false,
voices: Voices::from_start_request(
bp, request, navigator, screen, token,
)?,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::server::services::browser_profile_services::config::consts::LINUX_MOCK_PROFILE;
fn create_base_profile() -> BrowserProfileFullData {
LINUX_MOCK_PROFILE.clone()
}
fn create_navigator(locale: &str) -> Navigator {
Navigator {
locale: locale.to_string(),
..Navigator::default()
}
}
#[test]
fn test_windows_voices() -> Result<(), Error> {
let mut profile = create_base_profile();
profile.platform = Platform::Windows;
let request = StartRequest::get_mock();
let navigator = create_navigator("en-US");
let screen = Screen::default();
let token = String::new();
let voices = Voices::from_start_request(
&profile, &request, &navigator, &screen, &token,
)?;
let voices = voices.0;
assert!(!voices.is_empty());
assert!(voices.iter().any(|v| v.language == "en-US"));
Ok(())
}
#[test]
fn test_windows_voices_non_english() -> Result<(), Error> {
let mut profile = create_base_profile();
profile.platform = Platform::Windows;
let request = StartRequest::get_mock();
let navigator = create_navigator("en-CA");
let screen = Screen::default();
let token = String::new();
let voices = Voices::from_start_request(
&profile, &request, &navigator, &screen, &token,
)?;
let voices = voices.0;
assert!(!voices.is_empty());
assert!(voices.iter().any(|v| v.language == "en-CA"));
assert!(voices.iter().any(|v| v.language == "en-US"));
Ok(())
}
#[test]
fn test_macos_voices() -> Result<(), Error> {
let mut profile = create_base_profile();
profile.platform = Platform::Macos;
let request = StartRequest::get_mock();
let navigator = create_navigator("en-US");
let screen = Screen::default();
let token = String::new();
let voices = Voices::from_start_request(
&profile, &request, &navigator, &screen, &token,
)?;
let voices = voices.0;
assert!(!voices.is_empty());
assert!(voices.iter().any(|v| v.language == "en-US"));
Ok(())
}
#[test]
fn test_macos_voices_non_english() -> Result<(), Error> {
let mut profile = create_base_profile();
profile.platform = Platform::Macos;
let request = StartRequest::get_mock();
let navigator = create_navigator("fr-FR");
let screen = Screen::default();
let token = String::new();
let voices = Voices::from_start_request(
&profile, &request, &navigator, &screen, &token,
)?;
let voices = voices.0;
assert!(!voices.is_empty());
assert!(voices.iter().any(|v| v.language == "en-US"));
Ok(())
}
#[test]
fn test_linux_voices() -> Result<(), Error> {
let profile = create_base_profile(); let request = StartRequest::get_mock();
let navigator = create_navigator("en-US");
let screen = Screen::default();
let token = String::new();
let voices = Voices::from_start_request(
&profile, &request, &navigator, &screen, &token,
)?;
assert!(voices.0.is_empty());
Ok(())
}
#[test]
fn test_voice_structure() -> Result<(), Error> {
let mut profile = create_base_profile();
profile.platform = Platform::Windows;
let request = StartRequest::get_mock();
let navigator = create_navigator("en-US");
let screen = Screen::default();
let token = String::new();
let voices = Voices::from_start_request(
&profile, &request, &navigator, &screen, &token,
)?;
for voice in voices.0 {
assert!(!voice.language.is_empty());
assert!(!voice.name.is_empty());
}
Ok(())
}
}