diff --git a/crates/voicevox_core/src/user_dict/dict.rs b/crates/voicevox_core/src/user_dict/dict.rs index 2f851b138..e3bb640c9 100644 --- a/crates/voicevox_core/src/user_dict/dict.rs +++ b/crates/voicevox_core/src/user_dict/dict.rs @@ -31,7 +31,7 @@ impl Inner { f(&mut self.words.lock().unwrap_or_else(|e| panic!("{e}"))) } - async fn load(&self, store_path: &str) -> crate::Result<()> { + async fn load(&self, store_path: impl AsRef) -> crate::Result<()> { let words = async { let words = &A::fs_err_read(store_path).await?; let words = serde_json::from_slice::>(words)?; @@ -78,7 +78,7 @@ impl Inner { }) } - async fn save(&self, store_path: &str) -> crate::Result<()> { + async fn save(&self, store_path: impl AsRef) -> crate::Result<()> { A::fs_err_write( store_path, serde_json::to_vec(&self.words).expect("should not fail"), @@ -109,6 +109,8 @@ impl A { } pub(crate) mod blocking { + use std::path::Path; + use indexmap::IndexMap; use uuid::Uuid; @@ -122,7 +124,6 @@ pub(crate) mod blocking { #[derive(Debug, Default)] pub struct UserDict(Inner); - // TODO: 引数の`path`は全部`AsRef`にする impl self::UserDict { /// ユーザー辞書を作成する。 pub fn new() -> Self { @@ -133,9 +134,8 @@ pub(crate) mod blocking { self.0.to_json() } - // TODO: `&mut IndexMap<_>`を取れるようにする - pub fn with_words(&self, f: impl FnOnce(&IndexMap) -> R) -> R { - self.0.with_words(|words| f(words)) + pub fn with_words(&self, f: impl FnOnce(&mut IndexMap) -> R) -> R { + self.0.with_words(f) } /// ユーザー辞書をファイルから読み込む。 @@ -143,7 +143,7 @@ pub(crate) mod blocking { /// # Errors /// /// ファイルが読めなかった、または内容が不正だった場合はエラーを返す。 - pub fn load(&self, store_path: &str) -> Result<()> { + pub fn load(&self, store_path: impl AsRef) -> Result<()> { self.0.load(store_path).block_on() } @@ -168,7 +168,7 @@ pub(crate) mod blocking { } /// ユーザー辞書を保存する。 - pub fn save(&self, store_path: &str) -> Result<()> { + pub fn save(&self, store_path: impl AsRef) -> Result<()> { self.0.save(store_path).block_on() } @@ -180,6 +180,8 @@ pub(crate) mod blocking { } pub(crate) mod nonblocking { + use std::path::Path; + use indexmap::IndexMap; use uuid::Uuid; @@ -200,7 +202,6 @@ pub(crate) mod nonblocking { #[derive(Debug, Default)] pub struct UserDict(Inner); - // TODO: 引数の`path`は全部`AsRef`にする impl self::UserDict { /// ユーザー辞書を作成する。 pub fn new() -> Self { @@ -211,9 +212,8 @@ pub(crate) mod nonblocking { self.0.to_json() } - // TODO: `&mut IndexMap<_>`を取れるようにする - pub fn with_words(&self, f: impl FnOnce(&IndexMap) -> R) -> R { - self.0.with_words(|words| f(words)) + pub fn with_words(&self, f: impl FnOnce(&mut IndexMap) -> R) -> R { + self.0.with_words(f) } /// ユーザー辞書をファイルから読み込む。 @@ -221,7 +221,7 @@ pub(crate) mod nonblocking { /// # Errors /// /// ファイルが読めなかった、または内容が不正だった場合はエラーを返す。 - pub async fn load(&self, store_path: &str) -> Result<()> { + pub async fn load(&self, store_path: impl AsRef) -> Result<()> { self.0.load(store_path).await } @@ -246,7 +246,7 @@ pub(crate) mod nonblocking { } /// ユーザー辞書を保存する。 - pub async fn save(&self, store_path: &str) -> Result<()> { + pub async fn save(&self, store_path: impl AsRef) -> Result<()> { self.0.save(store_path).await } diff --git a/crates/voicevox_core_java_api/lib/src/main/java/jp/hiroshiba/voicevoxcore/UserDict.java b/crates/voicevox_core_java_api/lib/src/main/java/jp/hiroshiba/voicevoxcore/UserDict.java index 21f6843dd..7135365ff 100644 --- a/crates/voicevox_core_java_api/lib/src/main/java/jp/hiroshiba/voicevoxcore/UserDict.java +++ b/crates/voicevox_core_java_api/lib/src/main/java/jp/hiroshiba/voicevoxcore/UserDict.java @@ -7,6 +7,8 @@ import jakarta.annotation.Nonnull; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; +import java.io.File; +import java.nio.file.Path; import java.util.HashMap; import jp.hiroshiba.voicevoxcore.exceptions.LoadUserDictException; import jp.hiroshiba.voicevoxcore.exceptions.SaveUserDictException; @@ -70,6 +72,26 @@ public void importDict(UserDict dict) { rsImportDict(dict); } + /** + * ユーザー辞書を読み込む。 + * + * @param path ユーザー辞書のパス。 + * @throws LoadUserDictException ユーザー辞書を読み込めなかった場合。 + */ + public void load(Path path) throws LoadUserDictException { + load(path.toString()); + } + + /** + * ユーザー辞書を読み込む。 + * + * @param path ユーザー辞書のパス。 + * @throws LoadUserDictException ユーザー辞書を読み込めなかった場合。 + */ + public void load(File path) throws LoadUserDictException { + load(path.toString()); + } + /** * ユーザー辞書を読み込む。 * @@ -80,6 +102,26 @@ public void load(String path) throws LoadUserDictException { rsLoad(path); } + /** + * ユーザー辞書を保存する。 + * + * @param path ユーザー辞書のパス。 + * @throws SaveUserDictException ユーザー辞書を保存できなかった場合。 + */ + public void save(Path path) throws SaveUserDictException { + rsSave(path.toString()); + } + + /** + * ユーザー辞書を保存する。 + * + * @param path ユーザー辞書のパス。 + * @throws SaveUserDictException ユーザー辞書を保存できなかった場合。 + */ + public void save(File path) throws SaveUserDictException { + rsSave(path.toString()); + } + /** * ユーザー辞書を保存する。 * diff --git a/crates/voicevox_core_java_api/src/user_dict.rs b/crates/voicevox_core_java_api/src/user_dict.rs index df8b8270b..ceee1f42e 100644 --- a/crates/voicevox_core_java_api/src/user_dict.rs +++ b/crates/voicevox_core_java_api/src/user_dict.rs @@ -124,7 +124,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_UserDict_rsLoad<'local> .clone(); let path = env.get_string(&path)?; - let path = &Cow::from(&path); + let path = &*Cow::from(&path); internal.load(path)?; @@ -144,7 +144,7 @@ unsafe extern "system" fn Java_jp_hiroshiba_voicevoxcore_UserDict_rsSave<'local> .clone(); let path = env.get_string(&path)?; - let path = &Cow::from(&path); + let path = &*Cow::from(&path); internal.save(path)?; diff --git a/crates/voicevox_core_python_api/python/voicevox_core/_rust/asyncio.pyi b/crates/voicevox_core_python_api/python/voicevox_core/_rust/asyncio.pyi index b386d2d5a..d6359e038 100644 --- a/crates/voicevox_core_python_api/python/voicevox_core/_rust/asyncio.pyi +++ b/crates/voicevox_core_python_api/python/voicevox_core/_rust/asyncio.pyi @@ -431,7 +431,7 @@ class UserDict: """このオプジェクトの :class:`dict` としての表現。""" ... def __init__(self) -> None: ... - async def load(self, path: str) -> None: + async def load(self, path: Union[str, PathLike[str]]) -> None: """ファイルに保存されたユーザー辞書を読み込む。 Parameters @@ -440,7 +440,7 @@ class UserDict: ユーザー辞書のパス。 """ ... - async def save(self, path: str) -> None: + async def save(self, path: Union[str, PathLike[str]]) -> None: """ ユーザー辞書をファイルに保存する。 diff --git a/crates/voicevox_core_python_api/python/voicevox_core/_rust/blocking.pyi b/crates/voicevox_core_python_api/python/voicevox_core/_rust/blocking.pyi index 891ceb05e..cf4f1f5c6 100644 --- a/crates/voicevox_core_python_api/python/voicevox_core/_rust/blocking.pyi +++ b/crates/voicevox_core_python_api/python/voicevox_core/_rust/blocking.pyi @@ -426,7 +426,7 @@ class UserDict: """このオプジェクトの :class:`dict` としての表現。""" ... def __init__(self) -> None: ... - def load(self, path: str) -> None: + def load(self, path: Union[str, PathLike[str]]) -> None: """ファイルに保存されたユーザー辞書を読み込む。 Parameters @@ -435,7 +435,7 @@ class UserDict: ユーザー辞書のパス。 """ ... - def save(self, path: str) -> None: + def save(self, path: Union[str, PathLike[str]]) -> None: """ ユーザー辞書をファイルに保存する。 diff --git a/crates/voicevox_core_python_api/src/convert.rs b/crates/voicevox_core_python_api/src/convert.rs index 8152bc980..d4a867606 100644 --- a/crates/voicevox_core_python_api/src/convert.rs +++ b/crates/voicevox_core_python_api/src/convert.rs @@ -37,7 +37,6 @@ pub(crate) fn from_acceleration_mode(ob: &PyAny) -> PyResult { } } -// FIXME: `UserDict`についてはこれではなく、`PathBuf::extract`を直接使うようにする pub(crate) fn from_utf8_path(ob: &PyAny) -> PyResult { PathBuf::extract(ob)? .into_os_string() diff --git a/crates/voicevox_core_python_api/src/lib.rs b/crates/voicevox_core_python_api/src/lib.rs index 00b6e7102..24d28261d 100644 --- a/crates/voicevox_core_python_api/src/lib.rs +++ b/crates/voicevox_core_python_api/src/lib.rs @@ -734,11 +734,11 @@ mod blocking { Self::default() } - fn load(&self, path: &str, py: Python<'_>) -> PyResult<()> { + fn load(&self, path: PathBuf, py: Python<'_>) -> PyResult<()> { self.dict.load(path).into_py_result(py) } - fn save(&self, path: &str, py: Python<'_>) -> PyResult<()> { + fn save(&self, path: PathBuf, py: Python<'_>) -> PyResult<()> { self.dict.save(path).into_py_result(py) } @@ -1363,9 +1363,8 @@ mod asyncio { Self::default() } - fn load<'py>(&self, path: &str, py: Python<'py>) -> PyResult<&'py PyAny> { + fn load<'py>(&self, path: PathBuf, py: Python<'py>) -> PyResult<&'py PyAny> { let this = self.dict.clone(); - let path = path.to_owned(); pyo3_asyncio::tokio::future_into_py(py, async move { let result = this.load(&path).await; @@ -1373,9 +1372,8 @@ mod asyncio { }) } - fn save<'py>(&self, path: &str, py: Python<'py>) -> PyResult<&'py PyAny> { + fn save<'py>(&self, path: PathBuf, py: Python<'py>) -> PyResult<&'py PyAny> { let this = self.dict.clone(); - let path = path.to_owned(); pyo3_asyncio::tokio::future_into_py(py, async move { let result = this.save(&path).await;