Skip to content

Commit

Permalink
feat!: [Rust] UserDictWordのコンストラクトをビルダースタイルに
Browse files Browse the repository at this point in the history
  • Loading branch information
qryxip committed Feb 11, 2025
1 parent 849f5b0 commit e465f5e
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 35 deletions.
2 changes: 1 addition & 1 deletion crates/voicevox_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ pub use self::{
metas::{CharacterMeta, CharacterVersion, StyleId, StyleMeta, StyleType, VoiceModelMeta},
result::Result,
synthesizer::AccelerationMode,
user_dict::{UserDictWord, UserDictWordType},
user_dict::{UserDictWord, UserDictWordBuilder, UserDictWordType},
version::VERSION,
voice_model::VoiceModelId,
};
Expand Down
2 changes: 1 addition & 1 deletion crates/voicevox_core/src/user_dict/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ mod part_of_speech_data;
mod word;

pub(crate) use self::word::{to_zenkaku, validate_pronunciation, InvalidWordError};
pub use self::word::{UserDictWord, UserDictWordType};
pub use self::word::{UserDictWord, UserDictWordBuilder, UserDictWordType};
69 changes: 54 additions & 15 deletions crates/voicevox_core/src/user_dict/word.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ impl<'de> Deserialize<'de> for UserDictWord {
}
}

/// [`UserDictWord`]のビルダー。
pub struct UserDictWordBuilder {
accent_type: usize,
word_type: UserDictWordType,
priority: u32,
}

#[expect(clippy::enum_variant_names, reason = "特に理由はないので正されるべき")] // FIXME
#[derive(thiserror::Error, Debug, PartialEq)]
pub(crate) enum InvalidWordError {
Expand Down Expand Up @@ -94,23 +101,13 @@ static MORA_REGEX: LazyLock<Regex> = LazyLock::new(|| {
});
static SPACE_REGEX: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"\p{Z}").unwrap());

impl Default for UserDictWord {
fn default() -> Self {
Self {
surface: "".to_string(),
pronunciation: "".to_string(),
accent_type: 0,
word_type: UserDictWordType::CommonNoun,
priority: 0,
mora_count: 0,
}
}
}

impl UserDictWord {
// TODO: これビルダースタイルにすべきでは?
#[doc(alias = "voicevox_user_dict_word_make")]
pub fn new(
pub fn builder() -> UserDictWordBuilder {
Default::default()
}

fn new(
surface: &str,
pronunciation: String,
accent_type: usize,
Expand Down Expand Up @@ -233,6 +230,48 @@ pub(crate) fn to_zenkaku(surface: &str) -> String {
})
.collect()
}

impl UserDictWordBuilder {
/// アクセント型。
pub fn accent_type(self, accent_type: usize) -> Self {
Self {
accent_type,
..self
}
}

/// 単語の種類。
pub fn word_type(self, word_type: UserDictWordType) -> Self {
Self { word_type, ..self }
}

/// 単語の優先度。
pub fn priority(self, priority: u32) -> Self {
Self { priority, ..self }
}

/// [`UserDictWord`]をコンストラクトする。
pub fn build(self, surface: &str, pronunciation: String) -> crate::Result<UserDictWord> {
UserDictWord::new(
surface,
pronunciation,
self.accent_type,
self.word_type,
self.priority,
)
}
}

impl Default for UserDictWordBuilder {
fn default() -> Self {
Self {
accent_type: 0,
word_type: UserDictWordType::CommonNoun,
priority: 0, // FIXME: `5`では?
}
}
}

/// ユーザー辞書の単語の種類。
#[doc(alias = "VoicevoxUserDictWordType")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
Expand Down
16 changes: 9 additions & 7 deletions crates/voicevox_core_c_api/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,15 @@ pub(crate) impl uuid::Bytes {

impl VoicevoxUserDictWord {
pub(crate) unsafe fn try_into_word(&self) -> CApiResult<voicevox_core::UserDictWord> {
Ok(UserDictWord::new(
ensure_utf8(CStr::from_ptr(self.surface))?,
ensure_utf8(CStr::from_ptr(self.pronunciation))?.to_string(),
self.accent_type,
self.word_type.into(),
self.priority,
)?)
UserDictWord::builder()
.accent_type(self.accent_type)
.word_type(self.word_type.into())
.priority(self.priority)
.build(
ensure_utf8(CStr::from_ptr(self.surface))?,
ensure_utf8(CStr::from_ptr(self.pronunciation))?.to_string(),
)
.map_err(Into::into)
}
}

Expand Down
13 changes: 10 additions & 3 deletions crates/voicevox_core_c_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1440,12 +1440,19 @@ pub extern "C" fn voicevox_user_dict_word_make(
pronunciation: *const c_char,
) -> VoicevoxUserDictWord {
init_logger_once();
let default = UserDictWord::builder()
.build(
// dummy
"",
"ア".to_owned(),
)
.expect("should be valid");
VoicevoxUserDictWord {
surface,
pronunciation,
accent_type: UserDictWord::default().accent_type(),
word_type: UserDictWord::default().word_type().into(),
priority: UserDictWord::default().priority(),
accent_type: default.accent_type(),
word_type: default.word_type().into(),
priority: default.priority(),
}
}

Expand Down
17 changes: 9 additions & 8 deletions crates/voicevox_core_python_api/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,15 @@ pub(crate) fn to_py_uuid(py: Python<'_>, uuid: Uuid) -> PyResult<PyObject> {
Ok(uuid.to_object(py))
}
pub(crate) fn to_rust_user_dict_word(ob: &PyAny) -> PyResult<voicevox_core::UserDictWord> {
voicevox_core::UserDictWord::new(
ob.getattr("surface")?.extract()?,
ob.getattr("pronunciation")?.extract()?,
ob.getattr("accent_type")?.extract()?,
from_literal_choice(ob.getattr("word_type")?.extract()?)?,
ob.getattr("priority")?.extract()?,
)
.into_py_result(ob.py())
voicevox_core::UserDictWord::builder()
.accent_type(ob.getattr("accent_type")?.extract()?)
.word_type(from_literal_choice(ob.getattr("word_type")?.extract()?)?)
.priority(ob.getattr("priority")?.extract()?)
.build(
ob.getattr("surface")?.extract()?,
ob.getattr("pronunciation")?.extract()?,
)
.into_py_result(ob.py())
}
pub(crate) fn to_py_user_dict_word<'py>(
py: Python<'py>,
Expand Down

0 comments on commit e465f5e

Please sign in to comment.