1use std::path::Path;
5
6use super::folder_beside;
7
8pub(crate) fn platform_voice_dir(folder: &str, lang: &str) -> String {
13 let voice = if cfg!(target_arch = "wasm32") {
14 folder.to_owned()
15 } else {
16 let exe = std::env::current_exe().ok();
17 folder_beside(folder, exe.as_deref(), Path::is_dir)
18 };
19 format!("{voice}/{lang}")
20}
21
22#[cfg(not(target_arch = "wasm32"))]
26#[allow(clippy::unused_async)] pub async fn read_manifest(dir: &str, file: &str) -> Result<Option<String>, String> {
28 let path = format!("{dir}/{file}");
29 match std::fs::read_to_string(&path) {
30 Ok(text) => Ok(Some(text)),
31 Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None),
32 Err(e) => Err(format!("{path}: {e}")),
33 }
34}
35
36#[cfg(target_arch = "wasm32")]
40pub async fn read_manifest(dir: &str, file: &str) -> Result<Option<String>, String> {
41 let path = format!("{dir}/{file}");
42 Ok(macroquad::file::load_string(&path).await.ok())
43}
44
45#[cfg(test)]
46mod tests {
47 use std::future::Future;
48 use std::pin::pin;
49 use std::task::{Context, Poll, Waker};
50
51 use super::*;
52
53 fn block_on<F: Future>(future: F) -> F::Output {
55 let mut future = pin!(future);
56 let mut cx = Context::from_waker(Waker::noop());
57 loop {
58 if let Poll::Ready(v) = future.as_mut().poll(&mut cx) {
59 return v;
60 }
61 }
62 }
63
64 #[test]
67 fn without_a_voice_folder_there_is_no_manifest() {
68 let nowhere = tempfile::tempdir().unwrap();
69 let dir = format!("{}/voice/en", nowhere.path().display());
70 assert_eq!(block_on(read_manifest(&dir, "voice.ron")), Ok(None));
71 }
72
73 #[test]
74 fn a_manifest_that_cannot_be_read_is_an_error_naming_it() {
75 let odd = tempfile::tempdir().unwrap();
77 std::fs::create_dir_all(odd.path().join("voice.ron")).unwrap();
78 let dir = odd.path().display().to_string();
79 let error = block_on(read_manifest(&dir, "voice.ron")).unwrap_err();
80 let start = format!("{dir}/voice.ron: ");
81 assert!(error.starts_with(&start), "{error}");
82 }
83
84 #[test]
85 fn a_manifest_is_read_whole() {
86 let dir = tempfile::tempdir().unwrap();
87 std::fs::write(dir.path().join("voices.ron"), "(clips: [])").unwrap();
88 let dir = dir.path().display().to_string();
89 let text = block_on(read_manifest(&dir, "voices.ron"));
90 assert_eq!(text, Ok(Some("(clips: [])".to_owned())));
91 }
92
93 #[test]
94 fn the_voice_folder_is_the_scripts_language_under_the_voice_folder() {
95 let dir = platform_voice_dir("voice", "en");
96 assert!(dir.ends_with("voice/en"), "{dir}");
97 assert!(!dir.contains('\\'), "{dir}");
98 }
99}