Phase 1 (Infrastructure): - Docs: README.md, AGENTS.md, CHANGELOG.md - Tests: 26 tests (modes_test, filetree_api_test) - Examples: examples/sample.md, sample.json - CI/CD: .gitea/workflows/test.yml, release.yml - Runner: configuration scripts and guides Phase 2 (Quality): - Code quality: rustfmt/clippy config - Security: environment variables - Test coverage: 62 tests (+36) - Documentation: CONTRIBUTING.md, docs/api.yaml - Showcase: demo_features.md, developer_quickstart.md Test coverage: 75% Test pass rate: 100%
83 lines
2.4 KiB
Rust
83 lines
2.4 KiB
Rust
pub fn voice_for_lang(lang: &str) -> String {
|
|
match lang {
|
|
"zh_TW" => "Meijia",
|
|
"zh_CN" => "Ting-Ting",
|
|
"en_US" => "Samantha",
|
|
"en_GB" => "Daniel",
|
|
"ja_JP" => "Kyoko",
|
|
"ko_KR" => "Yuna",
|
|
"fr_FR" => "Amelie",
|
|
"de_DE" => "Anna",
|
|
_ => "Meijia",
|
|
}
|
|
.to_string()
|
|
}
|
|
|
|
pub fn phrase_for_lang(lang: &str) -> String {
|
|
match lang {
|
|
"zh_TW" | "zh_CN" => "語音測試一二三",
|
|
"en_US" | "en_GB" => "Test one two three",
|
|
"ja_JP" => "これはテストです",
|
|
"ko_KR" => "테스트입니다",
|
|
"fr_FR" => "Ceci est un test",
|
|
"de_DE" => "Das ist ein Test",
|
|
_ => "Test",
|
|
}
|
|
.to_string()
|
|
}
|
|
|
|
pub fn audio_devices() -> (Vec<String>, Vec<String>, String, String) {
|
|
let run = |t: &str| -> Vec<String> {
|
|
if let Ok(r) = std::process::Command::new("SwitchAudioSource")
|
|
.args(["-a", "-t", t, "-f", "json"])
|
|
.output()
|
|
{
|
|
String::from_utf8_lossy(&r.stdout)
|
|
.lines()
|
|
.filter_map(|l| {
|
|
serde_json::from_str::<serde_json::Value>(l)
|
|
.ok()
|
|
.and_then(|v| v["name"].as_str().map(|s| s.to_string()))
|
|
})
|
|
.collect()
|
|
} else {
|
|
vec![]
|
|
}
|
|
};
|
|
|
|
let current = |t: &str| -> String {
|
|
std::process::Command::new("SwitchAudioSource")
|
|
.args(["-c", "-t", t])
|
|
.output()
|
|
.map(|r| String::from_utf8_lossy(&r.stdout).trim().to_string())
|
|
.unwrap_or_default()
|
|
};
|
|
|
|
let out = run("output");
|
|
let inp = run("input");
|
|
let co = current("output");
|
|
let ci = current("input");
|
|
(out, inp, co, ci)
|
|
}
|
|
|
|
pub fn inject_audio_devices(
|
|
html: &str,
|
|
out: &[String],
|
|
inp: &[String],
|
|
cur_out: &str,
|
|
cur_in: &str,
|
|
) -> String {
|
|
let mut out_opts = String::from("<option value=\"\">🔊 System</option>");
|
|
for d in out {
|
|
let sel = if d == cur_out { " selected" } else { "" };
|
|
out_opts.push_str(&format!("<option value=\"{d}\"{sel}>{d}</option>"));
|
|
}
|
|
let mut inp_opts = String::from("<option value=\"\">🎤 System</option>");
|
|
for d in inp {
|
|
let sel = if d == cur_in { " selected" } else { "" };
|
|
inp_opts.push_str(&format!("<option value=\"{d}\"{sel}>{d}</option>"));
|
|
}
|
|
html.replace("{out_devs}", &out_opts)
|
|
.replace("{in_devs}", &inp_opts)
|
|
}
|