From 0cfbf94c4279640c12ea800e18363091f6cff7bc Mon Sep 17 00:00:00 2001 From: Ryo Yamashita Date: Sat, 25 Jan 2025 16:23:39 +0900 Subject: [PATCH] feat!: `#[non_exhaustive]` (#941) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 目的としては将来の後方互換性の確保のため。 いくつかのenumだけこのようにする。 ```rs #[expect( clippy::manual_non_exhaustive, reason = "バインディングを作るときはexhaustiveとして扱いたい" )] pub enum … { …, #[doc(hidden)] __NonExhaustive, } ``` PythonとJavaの列挙型も同様の後方互換性を抱えているはずなので、要対応。 See-also: https://github.com/VOICEVOX/voicevox_core/pull/941#issuecomment-2613819266 --- crates/voicevox_core/src/devices.rs | 1 + crates/voicevox_core/src/engine/model.rs | 3 +++ crates/voicevox_core/src/error.rs | 6 ++++++ crates/voicevox_core/src/metas.rs | 3 +++ crates/voicevox_core/src/synthesizer.rs | 7 +++++++ crates/voicevox_core/src/user_dict/word.rs | 2 ++ crates/voicevox_core_c_api/src/helpers.rs | 3 +++ crates/voicevox_core_java_api/src/common.rs | 1 + crates/voicevox_core_python_api/src/convert.rs | 1 + 9 files changed, 27 insertions(+) diff --git a/crates/voicevox_core/src/devices.rs b/crates/voicevox_core/src/devices.rs index 345346a30..654e8b981 100644 --- a/crates/voicevox_core/src/devices.rs +++ b/crates/voicevox_core/src/devices.rs @@ -66,6 +66,7 @@ fn test_gpu( /// # } /// ``` #[derive(Clone, Copy, PartialEq, Eq, Debug, BitAnd, Serialize, Deserialize)] +#[non_exhaustive] pub struct SupportedDevices { /// CPUが利用可能。 /// diff --git a/crates/voicevox_core/src/engine/model.rs b/crates/voicevox_core/src/engine/model.rs index 3a46b14d4..0f0d6cf8b 100644 --- a/crates/voicevox_core/src/engine/model.rs +++ b/crates/voicevox_core/src/engine/model.rs @@ -7,6 +7,7 @@ use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; /// モーラ(子音+母音)ごとの情報。 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[non_exhaustive] pub struct Mora { /// 文字。 pub text: String, @@ -24,6 +25,7 @@ pub struct Mora { /// AccentPhrase (アクセント句ごとの情報)。 #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[non_exhaustive] pub struct AccentPhrase { /// モーラの配列。 pub moras: Vec, @@ -48,6 +50,7 @@ impl AccentPhrase { /// AudioQuery (音声合成用のクエリ)。 #[derive(Clone, Deserialize, Serialize)] +#[non_exhaustive] pub struct AudioQuery { /// アクセント句の配列。 pub accent_phrases: Vec, diff --git a/crates/voicevox_core/src/error.rs b/crates/voicevox_core/src/error.rs index 12c5e9519..3323b5a57 100644 --- a/crates/voicevox_core/src/error.rs +++ b/crates/voicevox_core/src/error.rs @@ -123,6 +123,10 @@ pub(crate) enum ErrorRepr { } /// エラーの種類。 +#[expect( + clippy::manual_non_exhaustive, + reason = "バインディングを作るときはexhaustiveとして扱いたい" +)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum ErrorKind { /// open_jtalk辞書ファイルが読み込まれていない。 @@ -165,6 +169,8 @@ pub enum ErrorKind { UseUserDict, /// ユーザー辞書の単語のバリデーションに失敗した。 InvalidWord, + #[doc(hidden)] + __NonExhaustive, } pub(crate) type LoadModelResult = std::result::Result; diff --git a/crates/voicevox_core/src/metas.rs b/crates/voicevox_core/src/metas.rs index e76f9bfab..1fd580fb4 100644 --- a/crates/voicevox_core/src/metas.rs +++ b/crates/voicevox_core/src/metas.rs @@ -82,6 +82,7 @@ pub type VoiceModelMeta = Vec; /// **話者**(_speaker_)のメタ情報。 #[derive(Deserialize, Serialize, Clone)] +#[non_exhaustive] pub struct SpeakerMeta { /// 話者名。 pub name: String, @@ -141,6 +142,7 @@ impl SpeakerMeta { /// **スタイル**(_style_)のメタ情報。 #[derive(Deserialize, Serialize, Clone)] +#[non_exhaustive] pub struct StyleMeta { /// スタイルID。 pub id: StyleId, @@ -172,6 +174,7 @@ pub struct StyleMeta { )] #[strum(serialize_all = "snake_case")] #[serde(rename_all = "snake_case")] +#[non_exhaustive] pub enum StyleType { /// 音声合成クエリの作成と音声合成が可能。 #[default] diff --git a/crates/voicevox_core/src/synthesizer.rs b/crates/voicevox_core/src/synthesizer.rs index 6a3f0bb27..485147626 100644 --- a/crates/voicevox_core/src/synthesizer.rs +++ b/crates/voicevox_core/src/synthesizer.rs @@ -81,6 +81,10 @@ impl Default for TtsOptions { } /// ハードウェアアクセラレーションモードを設定する設定値。 +#[expect( + clippy::manual_non_exhaustive, + reason = "バインディングを作るときはexhaustiveとして扱いたい" +)] #[derive(Default, Clone, Copy, Debug, PartialEq, Eq)] pub enum AccelerationMode { /// 実行環境に合った適切なハードウェアアクセラレーションモードを選択する。 @@ -90,6 +94,8 @@ pub enum AccelerationMode { Cpu, /// ハードウェアアクセラレーションモードを"GPU"に設定する。 Gpu, + #[doc(hidden)] + __NonExhaustive, } struct InitializeOptions { @@ -251,6 +257,7 @@ impl Inner { [gpu, ..] => DeviceSpec::Gpu(gpu), } } + AccelerationMode::__NonExhaustive => unreachable!(), }; info!("{device_for_heavy}を利用します"); diff --git a/crates/voicevox_core/src/user_dict/word.rs b/crates/voicevox_core/src/user_dict/word.rs index afc023669..a717435cd 100644 --- a/crates/voicevox_core/src/user_dict/word.rs +++ b/crates/voicevox_core/src/user_dict/word.rs @@ -244,6 +244,8 @@ pub enum UserDictWordType { Adjective, /// 接尾辞。 Suffix, + #[doc(hidden)] + __NonExhaustive, } impl UserDictWord { diff --git a/crates/voicevox_core_c_api/src/helpers.rs b/crates/voicevox_core_c_api/src/helpers.rs index 51e876e3e..d3d0235c7 100644 --- a/crates/voicevox_core_c_api/src/helpers.rs +++ b/crates/voicevox_core_c_api/src/helpers.rs @@ -47,6 +47,7 @@ pub(crate) fn into_result_code_with_error(result: CApiResult<()>) -> VoicevoxRes WordNotFound => VOICEVOX_RESULT_USER_DICT_WORD_NOT_FOUND_ERROR, UseUserDict => VOICEVOX_RESULT_USE_USER_DICT_ERROR, InvalidWord => VOICEVOX_RESULT_INVALID_USER_DICT_WORD_ERROR, + __NonExhaustive => unreachable!(), }, Err(InvalidUtf8Input) => VOICEVOX_RESULT_INVALID_UTF8_INPUT_ERROR, Err(InvalidAudioQuery(_)) => VOICEVOX_RESULT_INVALID_AUDIO_QUERY_ERROR, @@ -99,6 +100,7 @@ impl From for VoicevoxAccelerationMode { Auto => Self::VOICEVOX_ACCELERATION_MODE_AUTO, Cpu => Self::VOICEVOX_ACCELERATION_MODE_CPU, Gpu => Self::VOICEVOX_ACCELERATION_MODE_GPU, + __NonExhaustive => unreachable!(), } } } @@ -186,6 +188,7 @@ impl From for VoicevoxUserDictWordType { Self::VOICEVOX_USER_DICT_WORD_TYPE_ADJECTIVE } voicevox_core::UserDictWordType::Suffix => Self::VOICEVOX_USER_DICT_WORD_TYPE_SUFFIX, + voicevox_core::UserDictWordType::__NonExhaustive => unreachable!(), } } } diff --git a/crates/voicevox_core_java_api/src/common.rs b/crates/voicevox_core_java_api/src/common.rs index 0648033a4..22e10c2dc 100644 --- a/crates/voicevox_core_java_api/src/common.rs +++ b/crates/voicevox_core_java_api/src/common.rs @@ -67,6 +67,7 @@ where "Exception", ), )* + voicevox_core::ErrorKind::__NonExhaustive => unreachable!(), } }; } diff --git a/crates/voicevox_core_python_api/src/convert.rs b/crates/voicevox_core_python_api/src/convert.rs index 416dc2ac1..7a19465ce 100644 --- a/crates/voicevox_core_python_api/src/convert.rs +++ b/crates/voicevox_core_python_api/src/convert.rs @@ -241,6 +241,7 @@ pub(crate) impl voicevox_core::Result { ErrorKind::WordNotFound => WordNotFoundError::new_err(msg), ErrorKind::UseUserDict => UseUserDictError::new_err(msg), ErrorKind::InvalidWord => InvalidWordError::new_err(msg), + ErrorKind::__NonExhaustive => unreachable!(), }; [top]