From 3dce8a8e887961c56ef9a10b9c8610922f17dfc0 Mon Sep 17 00:00:00 2001 From: Romain Ruetschi Date: Mon, 22 Apr 2024 16:06:32 +0200 Subject: [PATCH] Release v0.43.0 (#207) * Update `tonic` to v0.11 * Update `base64` to v0.22 * Bump version to 0.43.0 * Update changelog * Check each feature individually instead of powerset * Harmonize jobs names --- .../200-tendermint-rs-0.35.md | 0 .../breaking-changes/207-update-tonic.md | 2 + .changelog/v0.43.0/summary.md | 1 + .github/workflows/rust.yml | 8 +- CHANGELOG.md | 11 + Cargo.toml | 6 +- src/prost/google.protobuf.rs | 219 ++++++--- src/prost/google.protobuf.serde.rs | 442 +++++++++++++++--- src/prost/proto_descriptor.bin | Bin 758331 -> 762475 bytes 9 files changed, 557 insertions(+), 132 deletions(-) rename .changelog/{unreleased/features => v0.43.0/breaking-changes}/200-tendermint-rs-0.35.md (100%) create mode 100644 .changelog/v0.43.0/breaking-changes/207-update-tonic.md create mode 100644 .changelog/v0.43.0/summary.md diff --git a/.changelog/unreleased/features/200-tendermint-rs-0.35.md b/.changelog/v0.43.0/breaking-changes/200-tendermint-rs-0.35.md similarity index 100% rename from .changelog/unreleased/features/200-tendermint-rs-0.35.md rename to .changelog/v0.43.0/breaking-changes/200-tendermint-rs-0.35.md diff --git a/.changelog/v0.43.0/breaking-changes/207-update-tonic.md b/.changelog/v0.43.0/breaking-changes/207-update-tonic.md new file mode 100644 index 00000000..844b80c4 --- /dev/null +++ b/.changelog/v0.43.0/breaking-changes/207-update-tonic.md @@ -0,0 +1,2 @@ +- Update `tonic` to v0.11 + ([\#207](https://github.com/cosmos/ibc-proto-rs/pull/207)) \ No newline at end of file diff --git a/.changelog/v0.43.0/summary.md b/.changelog/v0.43.0/summary.md new file mode 100644 index 00000000..8e9d174e --- /dev/null +++ b/.changelog/v0.43.0/summary.md @@ -0,0 +1 @@ +This release updates `tendermint-proto` to v0.35.0 and `tonic` to v0.11.0. diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index f93962bb..c047df97 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -44,7 +44,7 @@ jobs: command: fmt args: --all -- --check - clippy_all_features: + clippy-all-features: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -59,7 +59,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} args: --all-features --all-targets - clippy_no_default_features: + clippy-no-default-features: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -74,7 +74,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} args: --no-default-features - check_features_powerset: + check-each-feature: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -85,7 +85,7 @@ jobs: override: true - uses: taiki-e/install-action@cargo-hack - uses: Swatinem/rust-cache@v1 - - run: cargo hack check --feature-powerset --no-dev-deps + - run: cargo hack check --each-feature --no-dev-deps test-stable: runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d39a708..6ee8b624 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # CHANGELOG +## v0.43.0 + +*April 22nd, 2024* + +This release updates `tendermint-proto` to v0.35.0 and `tonic` to v0.11.0. + +### BREAKING CHANGES + +- Update `tendermint-proto` to v0.35.0 ([\#200](https://github.com/cosmos/ibc-proto-rs/pull/200)) +- Update `tonic` to v0.11 ([\#207](https://github.com/cosmos/ibc-proto-rs/pull/207)) + ## v0.42.2 *March 14th, 2024* diff --git a/Cargo.toml b/Cargo.toml index 884366c5..146ad2ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ibc-proto" -version = "0.42.2" +version = "0.43.0" authors = ["Informal Systems "] edition = "2021" license = "Apache-2.0" @@ -30,11 +30,11 @@ all-features = true [dependencies] prost = { version = "0.12.3", default-features = false, features = ["prost-derive"] } bytes = { version = "1.2", default-features = false } -tonic = { version = "0.10", default-features = false, optional = true } +tonic = { version = "0.11", default-features = false, optional = true } serde = { version = "1.0", default-features = false, optional = true } schemars = { version = "0.8", optional = true } subtle-encoding = { version = "0.5", default-features = false } -base64 = { version = "0.21", default-features = false, features = ["alloc"] } +base64 = { version = "0.22", default-features = false, features = ["alloc"] } flex-error = { version = "0.4", default-features = false } ics23 = { version = "0.11.0", default-features = false } informalsystems-pbjson = { version = "0.7.0", optional = true, default-features = false } diff --git a/src/prost/google.protobuf.rs b/src/prost/google.protobuf.rs index a0dfa109..3f43790e 100644 --- a/src/prost/google.protobuf.rs +++ b/src/prost/google.protobuf.rs @@ -192,9 +192,9 @@ pub struct FileDescriptorProto { /// If `edition` is present, this value must be "editions". #[prost(string, optional, tag = "12")] pub syntax: ::core::option::Option<::prost::alloc::string::String>, - /// The edition of the proto file, which is an opaque string. - #[prost(string, optional, tag = "13")] - pub edition: ::core::option::Option<::prost::alloc::string::String>, + /// The edition of the proto file. + #[prost(enumeration = "Edition", optional, tag = "14")] + pub edition: ::core::option::Option, } impl ::prost::Name for FileDescriptorProto { const NAME: &'static str = "FileDescriptorProto"; @@ -294,7 +294,7 @@ pub struct ExtensionRangeOptions { #[prost(message, optional, tag = "50")] pub features: ::core::option::Option, /// The verification state of the range. - /// TODO(b/278783756): flip the default to DECLARATION once all empty ranges + /// TODO: flip the default to DECLARATION once all empty ranges /// are marked as UNVERIFIED. #[prost( enumeration = "extension_range_options::VerificationState", @@ -432,12 +432,12 @@ pub struct FieldDescriptorProto { /// If true, this is a proto3 "optional". When a proto3 field is optional, it /// tracks presence regardless of field type. /// - /// When proto3_optional is true, this field must be belong to a oneof to - /// signal to old proto3 clients that presence is tracked for this field. This - /// oneof is known as a "synthetic" oneof, and this field must be its sole - /// member (each proto3 optional field gets its own synthetic oneof). Synthetic - /// oneofs exist in the descriptor only, and do not generate any API. Synthetic - /// oneofs must be ordered after all "real" oneofs. + /// When proto3_optional is true, this field must belong to a oneof to signal + /// to old proto3 clients that presence is tracked for this field. This oneof + /// is known as a "synthetic" oneof, and this field must be its sole member + /// (each proto3 optional field gets its own synthetic oneof). Synthetic oneofs + /// exist in the descriptor only, and do not generate any API. Synthetic oneofs + /// must be ordered after all "real" oneofs. /// /// For message fields, proto3_optional doesn't create any semantic change, /// since non-repeated message fields always track presence. However it still @@ -484,9 +484,10 @@ pub mod field_descriptor_proto { Bool = 8, String = 9, /// Tag-delimited aggregate. - /// Group type is deprecated and not supported in proto3. However, Proto3 + /// Group type is deprecated and not supported after google.protobuf. However, Proto3 /// implementations should still be able to parse the group wire format and - /// treat group fields as unknown fields. + /// treat group fields as unknown fields. In Editions, the group wire format + /// can be enabled via the `message_encoding` feature. Group = 10, /// Length-delimited aggregate. Message = 11, @@ -568,8 +569,11 @@ pub mod field_descriptor_proto { pub enum Label { /// 0 is reserved for errors Optional = 1, - Required = 2, Repeated = 3, + /// The required label is only allowed in google.protobuf. In proto3 and Editions + /// it's explicitly prohibited. In Editions, the `field_presence` feature + /// can be used to get this behavior. + Required = 2, } impl Label { /// String value of the enum field names used in the ProtoBuf definition. @@ -579,16 +583,16 @@ pub mod field_descriptor_proto { pub fn as_str_name(&self) -> &'static str { match self { Label::Optional => "LABEL_OPTIONAL", - Label::Required => "LABEL_REQUIRED", Label::Repeated => "LABEL_REPEATED", + Label::Required => "LABEL_REQUIRED", } } /// Creates an enum from field names used in the ProtoBuf definition. pub fn from_str_name(value: &str) -> ::core::option::Option { match value { "LABEL_OPTIONAL" => Some(Self::Optional), - "LABEL_REQUIRED" => Some(Self::Required), "LABEL_REPEATED" => Some(Self::Repeated), + "LABEL_REQUIRED" => Some(Self::Required), _ => None, } } @@ -802,8 +806,6 @@ pub struct FileOptions { pub java_generic_services: ::core::option::Option, #[prost(bool, optional, tag = "18", default = "false")] pub py_generic_services: ::core::option::Option, - #[prost(bool, optional, tag = "42", default = "false")] - pub php_generic_services: ::core::option::Option, /// Is this file deprecated? /// Depending on the target platform, this can emit Deprecated annotations /// for everything in the file, or it will be completely ignored; in the very @@ -943,10 +945,6 @@ pub struct MessageOptions { /// this is a formalization for deprecating messages. #[prost(bool, optional, tag = "3", default = "false")] pub deprecated: ::core::option::Option, - /// NOTE: Do not set the option in .proto files. Always use the maps syntax - /// instead. The option should only be implicitly set by the proto compiler - /// parser. - /// /// Whether the message is an automatically generated map entry type for the /// maps field. /// @@ -964,6 +962,10 @@ pub struct MessageOptions { /// use a native map in the target language to hold the keys and values. /// The reflection APIs in such implementations still need to work as /// if the field is a repeated message field. + /// + /// NOTE: Do not set the option in .proto files. Always use the maps syntax + /// instead. The option should only be implicitly set by the proto compiler + /// parser. #[prost(bool, optional, tag = "7")] pub map_entry: ::core::option::Option, /// Enable the legacy handling of JSON field name conflicts. This lowercases @@ -974,7 +976,7 @@ pub struct MessageOptions { /// This should only be used as a temporary measure against broken builds due /// to the change in behavior for JSON field name conflicts. /// - /// TODO(b/261750190) This is legacy behavior we plan to remove once downstream + /// TODO This is legacy behavior we plan to remove once downstream /// teams have had time to migrate. #[deprecated] #[prost(bool, optional, tag = "11")] @@ -1013,7 +1015,9 @@ pub struct FieldOptions { /// a more efficient representation on the wire. Rather than repeatedly /// writing the tag and type for each element, the entire array is encoded as /// a single length-delimited blob. In proto3, only explicit setting it to - /// false will avoid using packed encoding. + /// false will avoid using packed encoding. This option is prohibited in + /// Editions, but the `repeated_field_encoding` feature can be used to control + /// the behavior. #[prost(bool, optional, tag = "2")] pub packed: ::core::option::Option, /// The jstype option determines the JavaScript type used for values of the @@ -1051,19 +1055,11 @@ pub struct FieldOptions { /// call from multiple threads concurrently, while non-const methods continue /// to require exclusive access. /// - /// Note that implementations may choose not to check required fields within - /// a lazy sub-message. That is, calling IsInitialized() on the outer message - /// may return true even if the inner message has missing required fields. - /// This is necessary because otherwise the inner message would have to be - /// parsed in order to perform the check, defeating the purpose of lazy - /// parsing. An implementation which chooses not to check required fields - /// must be consistent about it. That is, for any particular sub-message, the - /// implementation must either *always* check its required fields, or *never* - /// check its required fields, regardless of whether or not the message has - /// been parsed. - /// - /// As of May 2022, lazy verifies the contents of the byte stream during - /// parsing. An invalid byte stream will cause the overall parsing to fail. + /// Note that lazy message fields are still eagerly verified to check + /// ill-formed wireformat or missing required fields. Calling IsInitialized() + /// on the outer message would fail if the inner message has missing required + /// fields. Failed verification would result in parsing failure (except when + /// uninitialized messages are acceptable). #[prost(bool, optional, tag = "5", default = "false")] pub lazy: ::core::option::Option, /// unverified_lazy does no correctness checks on the byte stream. This should @@ -1107,8 +1103,8 @@ pub mod field_options { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct EditionDefault { - #[prost(string, optional, tag = "1")] - pub edition: ::core::option::Option<::prost::alloc::string::String>, + #[prost(enumeration = "super::Edition", optional, tag = "3")] + pub edition: ::core::option::Option, /// Textproto value. #[prost(string, optional, tag = "2")] pub value: ::core::option::Option<::prost::alloc::string::String>, @@ -1358,7 +1354,7 @@ pub struct EnumOptions { /// and strips underscored from the fields before comparison in proto3 only. /// The new behavior takes `json_name` into account and applies to proto2 as /// well. - /// TODO(b/261750190) Remove this legacy behavior once downstream teams have + /// TODO Remove this legacy behavior once downstream teams have /// had time to migrate. #[deprecated] #[prost(bool, optional, tag = "6")] @@ -1561,7 +1557,7 @@ impl ::prost::Name for UninterpretedOption { ::prost::alloc::format!("google.protobuf.{}", Self::NAME) } } -/// TODO(b/274655146) Enums in C++ gencode (and potentially other languages) are +/// TODO Enums in C++ gencode (and potentially other languages) are /// not well scoped. This means that each of the feature enums below can clash /// with each other. The short names we've chosen maximize call-site /// readability, but leave us very open to this scenario. A future feature will @@ -1576,14 +1572,12 @@ pub struct FeatureSet { pub enum_type: ::core::option::Option, #[prost(enumeration = "feature_set::RepeatedFieldEncoding", optional, tag = "3")] pub repeated_field_encoding: ::core::option::Option, - #[prost(enumeration = "feature_set::StringFieldValidation", optional, tag = "4")] - pub string_field_validation: ::core::option::Option, + #[prost(enumeration = "feature_set::Utf8Validation", optional, tag = "4")] + pub utf8_validation: ::core::option::Option, #[prost(enumeration = "feature_set::MessageEncoding", optional, tag = "5")] pub message_encoding: ::core::option::Option, #[prost(enumeration = "feature_set::JsonFormat", optional, tag = "6")] pub json_format: ::core::option::Option, - #[prost(message, optional, boxed, tag = "999")] - pub raw_features: ::core::option::Option<::prost::alloc::boxed::Box>, } /// Nested message and enum types in `FeatureSet`. pub mod feature_set { @@ -1719,31 +1713,28 @@ pub mod feature_set { ::prost::Enumeration )] #[repr(i32)] - pub enum StringFieldValidation { + pub enum Utf8Validation { Unknown = 0, - Mandatory = 1, - Hint = 2, + Verify = 2, None = 3, } - impl StringFieldValidation { + impl Utf8Validation { /// String value of the enum field names used in the ProtoBuf definition. /// /// The values are not transformed in any way and thus are considered stable /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - StringFieldValidation::Unknown => "STRING_FIELD_VALIDATION_UNKNOWN", - StringFieldValidation::Mandatory => "MANDATORY", - StringFieldValidation::Hint => "HINT", - StringFieldValidation::None => "NONE", + Utf8Validation::Unknown => "UTF8_VALIDATION_UNKNOWN", + Utf8Validation::Verify => "VERIFY", + Utf8Validation::None => "NONE", } } /// Creates an enum from field names used in the ProtoBuf definition. pub fn from_str_name(value: &str) -> ::core::option::Option { match value { - "STRING_FIELD_VALIDATION_UNKNOWN" => Some(Self::Unknown), - "MANDATORY" => Some(Self::Mandatory), - "HINT" => Some(Self::Hint), + "UTF8_VALIDATION_UNKNOWN" => Some(Self::Unknown), + "VERIFY" => Some(Self::Verify), "NONE" => Some(Self::None), _ => None, } @@ -1835,6 +1826,55 @@ impl ::prost::Name for FeatureSet { ::prost::alloc::format!("google.protobuf.{}", Self::NAME) } } +/// A compiled specification for the defaults of a set of features. These +/// messages are generated from FeatureSet extensions and can be used to seed +/// feature resolution. The resolution with this object becomes a simple search +/// for the closest matching edition, followed by proto merges. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct FeatureSetDefaults { + #[prost(message, repeated, tag = "1")] + pub defaults: ::prost::alloc::vec::Vec< + feature_set_defaults::FeatureSetEditionDefault, + >, + /// The minimum supported edition (inclusive) when this was constructed. + /// Editions before this will not have defaults. + #[prost(enumeration = "Edition", optional, tag = "4")] + pub minimum_edition: ::core::option::Option, + /// The maximum known edition (inclusive) when this was constructed. Editions + /// after this will not have reliable defaults. + #[prost(enumeration = "Edition", optional, tag = "5")] + pub maximum_edition: ::core::option::Option, +} +/// Nested message and enum types in `FeatureSetDefaults`. +pub mod feature_set_defaults { + /// A map from every known edition with a unique set of defaults to its + /// defaults. Not all editions may be contained here. For a given edition, + /// the defaults at the closest matching edition ordered at or before it should + /// be used. This field must be in strict ascending order by edition. + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct FeatureSetEditionDefault { + #[prost(enumeration = "super::Edition", optional, tag = "3")] + pub edition: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub features: ::core::option::Option, + } + impl ::prost::Name for FeatureSetEditionDefault { + const NAME: &'static str = "FeatureSetEditionDefault"; + const PACKAGE: &'static str = "google.protobuf"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("google.protobuf.FeatureSetDefaults.{}", Self::NAME) + } + } +} +impl ::prost::Name for FeatureSetDefaults { + const NAME: &'static str = "FeatureSetDefaults"; + const PACKAGE: &'static str = "google.protobuf"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("google.protobuf.{}", Self::NAME) + } +} /// Encapsulates information about the original source file from which a /// FileDescriptorProto was generated. #[allow(clippy::derive_partial_eq_without_eq)] @@ -1895,7 +1935,7 @@ pub mod source_code_info { /// location. /// /// Each element is a field number or an index. They form a path from - /// the root FileDescriptorProto to the place where the definition occurs. + /// the root FileDescriptorProto to the place where the definition appears. /// For example, this path: /// \[ 4, 3, 2, 7, 1 \] /// refers to: @@ -2091,6 +2131,73 @@ impl ::prost::Name for GeneratedCodeInfo { ::prost::alloc::format!("google.protobuf.{}", Self::NAME) } } +/// The full set of known editions. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum Edition { + /// A placeholder for an unknown edition value. + Unknown = 0, + /// Legacy syntax "editions". These pre-date editions, but behave much like + /// distinct editions. These can't be used to specify the edition of proto + /// files, but feature definitions must supply proto2/proto3 defaults for + /// backwards compatibility. + Proto2 = 998, + Proto3 = 999, + /// Editions that have been released. The specific values are arbitrary and + /// should not be depended on, but they will always be time-ordered for easy + /// comparison. + Edition2023 = 1000, + Edition2024 = 1001, + /// Placeholder editions for testing feature resolution. These should not be + /// used or relyed on outside of tests. + Edition1TestOnly = 1, + Edition2TestOnly = 2, + Edition99997TestOnly = 99997, + Edition99998TestOnly = 99998, + Edition99999TestOnly = 99999, + /// Placeholder for specifying unbounded edition support. This should only + /// ever be used by plugins that can expect to never require any changes to + /// support a new edition. + Max = 2147483647, +} +impl Edition { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Edition::Unknown => "EDITION_UNKNOWN", + Edition::Proto2 => "EDITION_PROTO2", + Edition::Proto3 => "EDITION_PROTO3", + Edition::Edition2023 => "EDITION_2023", + Edition::Edition2024 => "EDITION_2024", + Edition::Edition1TestOnly => "EDITION_1_TEST_ONLY", + Edition::Edition2TestOnly => "EDITION_2_TEST_ONLY", + Edition::Edition99997TestOnly => "EDITION_99997_TEST_ONLY", + Edition::Edition99998TestOnly => "EDITION_99998_TEST_ONLY", + Edition::Edition99999TestOnly => "EDITION_99999_TEST_ONLY", + Edition::Max => "EDITION_MAX", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "EDITION_UNKNOWN" => Some(Self::Unknown), + "EDITION_PROTO2" => Some(Self::Proto2), + "EDITION_PROTO3" => Some(Self::Proto3), + "EDITION_2023" => Some(Self::Edition2023), + "EDITION_2024" => Some(Self::Edition2024), + "EDITION_1_TEST_ONLY" => Some(Self::Edition1TestOnly), + "EDITION_2_TEST_ONLY" => Some(Self::Edition2TestOnly), + "EDITION_99997_TEST_ONLY" => Some(Self::Edition99997TestOnly), + "EDITION_99998_TEST_ONLY" => Some(Self::Edition99998TestOnly), + "EDITION_99999_TEST_ONLY" => Some(Self::Edition99999TestOnly), + "EDITION_MAX" => Some(Self::Max), + _ => None, + } + } +} /// A Timestamp represents a point in time independent of any time zone or local /// calendar, encoded as a count of seconds and fractions of seconds at /// nanosecond resolution. The count is relative to an epoch at UTC midnight on diff --git a/src/prost/google.protobuf.serde.rs b/src/prost/google.protobuf.serde.rs index 0c8064dd..4a8362c6 100644 --- a/src/prost/google.protobuf.serde.rs +++ b/src/prost/google.protobuf.serde.rs @@ -714,6 +714,104 @@ impl<'de> serde::Deserialize<'de> for Duration { deserializer.deserialize_struct("google.protobuf.Duration", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for Edition { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> core::result::Result + where + S: serde::Serializer, + { + let variant = match self { + Self::Unknown => "EDITION_UNKNOWN", + Self::Proto2 => "EDITION_PROTO2", + Self::Proto3 => "EDITION_PROTO3", + Self::Edition2023 => "EDITION_2023", + Self::Edition2024 => "EDITION_2024", + Self::Edition1TestOnly => "EDITION_1_TEST_ONLY", + Self::Edition2TestOnly => "EDITION_2_TEST_ONLY", + Self::Edition99997TestOnly => "EDITION_99997_TEST_ONLY", + Self::Edition99998TestOnly => "EDITION_99998_TEST_ONLY", + Self::Edition99999TestOnly => "EDITION_99999_TEST_ONLY", + Self::Max => "EDITION_MAX", + }; + serializer.serialize_str(variant) + } +} +impl<'de> serde::Deserialize<'de> for Edition { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> core::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "EDITION_UNKNOWN", + "EDITION_PROTO2", + "EDITION_PROTO3", + "EDITION_2023", + "EDITION_2024", + "EDITION_1_TEST_ONLY", + "EDITION_2_TEST_ONLY", + "EDITION_99997_TEST_ONLY", + "EDITION_99998_TEST_ONLY", + "EDITION_99999_TEST_ONLY", + "EDITION_MAX", + ]; + + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = Edition; + + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + fn visit_i64(self, v: i64) -> core::result::Result + where + E: serde::de::Error, + { + i32::try_from(v) + .ok() + .and_then(|x| x.try_into().ok()) + .ok_or_else(|| { + serde::de::Error::invalid_value(serde::de::Unexpected::Signed(v), &self) + }) + } + + fn visit_u64(self, v: u64) -> core::result::Result + where + E: serde::de::Error, + { + i32::try_from(v) + .ok() + .and_then(|x| x.try_into().ok()) + .ok_or_else(|| { + serde::de::Error::invalid_value(serde::de::Unexpected::Unsigned(v), &self) + }) + } + + fn visit_str(self, value: &str) -> core::result::Result + where + E: serde::de::Error, + { + match value { + "EDITION_UNKNOWN" => Ok(Edition::Unknown), + "EDITION_PROTO2" => Ok(Edition::Proto2), + "EDITION_PROTO3" => Ok(Edition::Proto3), + "EDITION_2023" => Ok(Edition::Edition2023), + "EDITION_2024" => Ok(Edition::Edition2024), + "EDITION_1_TEST_ONLY" => Ok(Edition::Edition1TestOnly), + "EDITION_2_TEST_ONLY" => Ok(Edition::Edition2TestOnly), + "EDITION_99997_TEST_ONLY" => Ok(Edition::Edition99997TestOnly), + "EDITION_99998_TEST_ONLY" => Ok(Edition::Edition99998TestOnly), + "EDITION_99999_TEST_ONLY" => Ok(Edition::Edition99999TestOnly), + "EDITION_MAX" => Ok(Edition::Max), + _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), + } + } + } + deserializer.deserialize_any(GeneratedVisitor) + } +} impl serde::Serialize for EnumDescriptorProto { #[allow(deprecated)] fn serialize(&self, serializer: S) -> core::result::Result @@ -1824,9 +1922,6 @@ impl serde::Serialize for FeatureSet { if true { len += 1; } - if true { - len += 1; - } let mut struct_ser = serializer.serialize_struct("google.protobuf.FeatureSet", len)?; if let Some(v) = self.field_presence.as_ref() { let v = feature_set::FieldPresence::try_from(*v) @@ -1843,10 +1938,10 @@ impl serde::Serialize for FeatureSet { .map_err(|_| serde::ser::Error::custom(::alloc::format!("Invalid variant {}", *v)))?; struct_ser.serialize_field("repeatedFieldEncoding", &v)?; } - if let Some(v) = self.string_field_validation.as_ref() { - let v = feature_set::StringFieldValidation::try_from(*v) + if let Some(v) = self.utf8_validation.as_ref() { + let v = feature_set::Utf8Validation::try_from(*v) .map_err(|_| serde::ser::Error::custom(::alloc::format!("Invalid variant {}", *v)))?; - struct_ser.serialize_field("stringFieldValidation", &v)?; + struct_ser.serialize_field("utf8Validation", &v)?; } if let Some(v) = self.message_encoding.as_ref() { let v = feature_set::MessageEncoding::try_from(*v) @@ -1858,9 +1953,6 @@ impl serde::Serialize for FeatureSet { .map_err(|_| serde::ser::Error::custom(::alloc::format!("Invalid variant {}", *v)))?; struct_ser.serialize_field("jsonFormat", &v)?; } - if let Some(v) = self.raw_features.as_ref() { - struct_ser.serialize_field("rawFeatures", v)?; - } struct_ser.end() } } @@ -1877,14 +1969,12 @@ impl<'de> serde::Deserialize<'de> for FeatureSet { "enumType", "repeated_field_encoding", "repeatedFieldEncoding", - "string_field_validation", - "stringFieldValidation", + "utf8_validation", + "utf8Validation", "message_encoding", "messageEncoding", "json_format", "jsonFormat", - "raw_features", - "rawFeatures", ]; #[allow(clippy::enum_variant_names)] @@ -1892,10 +1982,9 @@ impl<'de> serde::Deserialize<'de> for FeatureSet { FieldPresence, EnumType, RepeatedFieldEncoding, - StringFieldValidation, + Utf8Validation, MessageEncoding, JsonFormat, - RawFeatures, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> core::result::Result @@ -1920,10 +2009,9 @@ impl<'de> serde::Deserialize<'de> for FeatureSet { "fieldPresence" | "field_presence" => Ok(GeneratedField::FieldPresence), "enumType" | "enum_type" => Ok(GeneratedField::EnumType), "repeatedFieldEncoding" | "repeated_field_encoding" => Ok(GeneratedField::RepeatedFieldEncoding), - "stringFieldValidation" | "string_field_validation" => Ok(GeneratedField::StringFieldValidation), + "utf8Validation" | "utf8_validation" => Ok(GeneratedField::Utf8Validation), "messageEncoding" | "message_encoding" => Ok(GeneratedField::MessageEncoding), "jsonFormat" | "json_format" => Ok(GeneratedField::JsonFormat), - "rawFeatures" | "raw_features" => Ok(GeneratedField::RawFeatures), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -1946,10 +2034,9 @@ impl<'de> serde::Deserialize<'de> for FeatureSet { let mut field_presence__ = None; let mut enum_type__ = None; let mut repeated_field_encoding__ = None; - let mut string_field_validation__ = None; + let mut utf8_validation__ = None; let mut message_encoding__ = None; let mut json_format__ = None; - let mut raw_features__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::FieldPresence => { @@ -1970,11 +2057,11 @@ impl<'de> serde::Deserialize<'de> for FeatureSet { } repeated_field_encoding__ = map_.next_value::<::core::option::Option>()?.map(|x| x as i32); } - GeneratedField::StringFieldValidation => { - if string_field_validation__.is_some() { - return Err(serde::de::Error::duplicate_field("stringFieldValidation")); + GeneratedField::Utf8Validation => { + if utf8_validation__.is_some() { + return Err(serde::de::Error::duplicate_field("utf8Validation")); } - string_field_validation__ = map_.next_value::<::core::option::Option>()?.map(|x| x as i32); + utf8_validation__ = map_.next_value::<::core::option::Option>()?.map(|x| x as i32); } GeneratedField::MessageEncoding => { if message_encoding__.is_some() { @@ -1988,22 +2075,15 @@ impl<'de> serde::Deserialize<'de> for FeatureSet { } json_format__ = map_.next_value::<::core::option::Option>()?.map(|x| x as i32); } - GeneratedField::RawFeatures => { - if raw_features__.is_some() { - return Err(serde::de::Error::duplicate_field("rawFeatures")); - } - raw_features__ = map_.next_value()?; - } } } Ok(FeatureSet { field_presence: field_presence__, enum_type: enum_type__, repeated_field_encoding: repeated_field_encoding__, - string_field_validation: string_field_validation__, + utf8_validation: utf8_validation__, message_encoding: message_encoding__, json_format: json_format__, - raw_features: raw_features__, }) } } @@ -2383,38 +2463,36 @@ impl<'de> serde::Deserialize<'de> for feature_set::RepeatedFieldEncoding { deserializer.deserialize_any(GeneratedVisitor) } } -impl serde::Serialize for feature_set::StringFieldValidation { +impl serde::Serialize for feature_set::Utf8Validation { #[allow(deprecated)] fn serialize(&self, serializer: S) -> core::result::Result where S: serde::Serializer, { let variant = match self { - Self::Unknown => "STRING_FIELD_VALIDATION_UNKNOWN", - Self::Mandatory => "MANDATORY", - Self::Hint => "HINT", + Self::Unknown => "UTF8_VALIDATION_UNKNOWN", + Self::Verify => "VERIFY", Self::None => "NONE", }; serializer.serialize_str(variant) } } -impl<'de> serde::Deserialize<'de> for feature_set::StringFieldValidation { +impl<'de> serde::Deserialize<'de> for feature_set::Utf8Validation { #[allow(deprecated)] fn deserialize(deserializer: D) -> core::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "STRING_FIELD_VALIDATION_UNKNOWN", - "MANDATORY", - "HINT", + "UTF8_VALIDATION_UNKNOWN", + "VERIFY", "NONE", ]; struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = feature_set::StringFieldValidation; + type Value = feature_set::Utf8Validation; fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(formatter, "expected one of: {:?}", &FIELDS) @@ -2449,10 +2527,9 @@ impl<'de> serde::Deserialize<'de> for feature_set::StringFieldValidation { E: serde::de::Error, { match value { - "STRING_FIELD_VALIDATION_UNKNOWN" => Ok(feature_set::StringFieldValidation::Unknown), - "MANDATORY" => Ok(feature_set::StringFieldValidation::Mandatory), - "HINT" => Ok(feature_set::StringFieldValidation::Hint), - "NONE" => Ok(feature_set::StringFieldValidation::None), + "UTF8_VALIDATION_UNKNOWN" => Ok(feature_set::Utf8Validation::Unknown), + "VERIFY" => Ok(feature_set::Utf8Validation::Verify), + "NONE" => Ok(feature_set::Utf8Validation::None), _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), } } @@ -2460,6 +2537,247 @@ impl<'de> serde::Deserialize<'de> for feature_set::StringFieldValidation { deserializer.deserialize_any(GeneratedVisitor) } } +impl serde::Serialize for FeatureSetDefaults { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> core::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if true { + len += 1; + } + if true { + len += 1; + } + if true { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("google.protobuf.FeatureSetDefaults", len)?; + if true { + struct_ser.serialize_field("defaults", &self.defaults)?; + } + if let Some(v) = self.minimum_edition.as_ref() { + let v = Edition::try_from(*v) + .map_err(|_| serde::ser::Error::custom(::alloc::format!("Invalid variant {}", *v)))?; + struct_ser.serialize_field("minimumEdition", &v)?; + } + if let Some(v) = self.maximum_edition.as_ref() { + let v = Edition::try_from(*v) + .map_err(|_| serde::ser::Error::custom(::alloc::format!("Invalid variant {}", *v)))?; + struct_ser.serialize_field("maximumEdition", &v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for FeatureSetDefaults { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> core::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "defaults", + "minimum_edition", + "minimumEdition", + "maximum_edition", + "maximumEdition", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Defaults, + MinimumEdition, + MaximumEdition, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> core::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> core::result::Result + where + E: serde::de::Error, + { + match value { + "defaults" => Ok(GeneratedField::Defaults), + "minimumEdition" | "minimum_edition" => Ok(GeneratedField::MinimumEdition), + "maximumEdition" | "maximum_edition" => Ok(GeneratedField::MaximumEdition), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = FeatureSetDefaults; + + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + formatter.write_str("struct google.protobuf.FeatureSetDefaults") + } + + fn visit_map(self, mut map_: V) -> core::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut defaults__ = None; + let mut minimum_edition__ = None; + let mut maximum_edition__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Defaults => { + if defaults__.is_some() { + return Err(serde::de::Error::duplicate_field("defaults")); + } + defaults__ = Some(map_.next_value()?); + } + GeneratedField::MinimumEdition => { + if minimum_edition__.is_some() { + return Err(serde::de::Error::duplicate_field("minimumEdition")); + } + minimum_edition__ = map_.next_value::<::core::option::Option>()?.map(|x| x as i32); + } + GeneratedField::MaximumEdition => { + if maximum_edition__.is_some() { + return Err(serde::de::Error::duplicate_field("maximumEdition")); + } + maximum_edition__ = map_.next_value::<::core::option::Option>()?.map(|x| x as i32); + } + } + } + Ok(FeatureSetDefaults { + defaults: defaults__.unwrap_or_default(), + minimum_edition: minimum_edition__, + maximum_edition: maximum_edition__, + }) + } + } + deserializer.deserialize_struct("google.protobuf.FeatureSetDefaults", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for feature_set_defaults::FeatureSetEditionDefault { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> core::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if true { + len += 1; + } + if true { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault", len)?; + if let Some(v) = self.edition.as_ref() { + let v = Edition::try_from(*v) + .map_err(|_| serde::ser::Error::custom(::alloc::format!("Invalid variant {}", *v)))?; + struct_ser.serialize_field("edition", &v)?; + } + if let Some(v) = self.features.as_ref() { + struct_ser.serialize_field("features", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for feature_set_defaults::FeatureSetEditionDefault { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> core::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "edition", + "features", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Edition, + Features, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> core::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> core::result::Result + where + E: serde::de::Error, + { + match value { + "edition" => Ok(GeneratedField::Edition), + "features" => Ok(GeneratedField::Features), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = feature_set_defaults::FeatureSetEditionDefault; + + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + formatter.write_str("struct google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault") + } + + fn visit_map(self, mut map_: V) -> core::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut edition__ = None; + let mut features__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Edition => { + if edition__.is_some() { + return Err(serde::de::Error::duplicate_field("edition")); + } + edition__ = map_.next_value::<::core::option::Option>()?.map(|x| x as i32); + } + GeneratedField::Features => { + if features__.is_some() { + return Err(serde::de::Error::duplicate_field("features")); + } + features__ = map_.next_value()?; + } + } + } + Ok(feature_set_defaults::FeatureSetEditionDefault { + edition: edition__, + features: features__, + }) + } + } + deserializer.deserialize_struct("google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for FieldDescriptorProto { #[allow(deprecated)] fn serialize(&self, serializer: S) -> core::result::Result @@ -2742,8 +3060,8 @@ impl serde::Serialize for field_descriptor_proto::Label { { let variant = match self { Self::Optional => "LABEL_OPTIONAL", - Self::Required => "LABEL_REQUIRED", Self::Repeated => "LABEL_REPEATED", + Self::Required => "LABEL_REQUIRED", }; serializer.serialize_str(variant) } @@ -2756,8 +3074,8 @@ impl<'de> serde::Deserialize<'de> for field_descriptor_proto::Label { { const FIELDS: &[&str] = &[ "LABEL_OPTIONAL", - "LABEL_REQUIRED", "LABEL_REPEATED", + "LABEL_REQUIRED", ]; struct GeneratedVisitor; @@ -2799,8 +3117,8 @@ impl<'de> serde::Deserialize<'de> for field_descriptor_proto::Label { { match value { "LABEL_OPTIONAL" => Ok(field_descriptor_proto::Label::Optional), - "LABEL_REQUIRED" => Ok(field_descriptor_proto::Label::Required), "LABEL_REPEATED" => Ok(field_descriptor_proto::Label::Repeated), + "LABEL_REQUIRED" => Ok(field_descriptor_proto::Label::Required), _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), } } @@ -3326,7 +3644,9 @@ impl serde::Serialize for field_options::EditionDefault { } let mut struct_ser = serializer.serialize_struct("google.protobuf.FieldOptions.EditionDefault", len)?; if let Some(v) = self.edition.as_ref() { - struct_ser.serialize_field("edition", v)?; + let v = Edition::try_from(*v) + .map_err(|_| serde::ser::Error::custom(::alloc::format!("Invalid variant {}", *v)))?; + struct_ser.serialize_field("edition", &v)?; } if let Some(v) = self.value.as_ref() { struct_ser.serialize_field("value", v)?; @@ -3399,7 +3719,7 @@ impl<'de> serde::Deserialize<'de> for field_options::EditionDefault { if edition__.is_some() { return Err(serde::de::Error::duplicate_field("edition")); } - edition__ = map_.next_value()?; + edition__ = map_.next_value::<::core::option::Option>()?.map(|x| x as i32); } GeneratedField::Value => { if value__.is_some() { @@ -3746,7 +4066,9 @@ impl serde::Serialize for FileDescriptorProto { struct_ser.serialize_field("syntax", v)?; } if let Some(v) = self.edition.as_ref() { - struct_ser.serialize_field("edition", v)?; + let v = Edition::try_from(*v) + .map_err(|_| serde::ser::Error::custom(::alloc::format!("Invalid variant {}", *v)))?; + struct_ser.serialize_field("edition", &v)?; } struct_ser.end() } @@ -3943,7 +4265,7 @@ impl<'de> serde::Deserialize<'de> for FileDescriptorProto { if edition__.is_some() { return Err(serde::de::Error::duplicate_field("edition")); } - edition__ = map_.next_value()?; + edition__ = map_.next_value::<::core::option::Option>()?.map(|x| x as i32); } } } @@ -4129,9 +4451,6 @@ impl serde::Serialize for FileOptions { if true { len += 1; } - if true { - len += 1; - } let mut struct_ser = serializer.serialize_struct("google.protobuf.FileOptions", len)?; if let Some(v) = self.java_package.as_ref() { struct_ser.serialize_field("javaPackage", v)?; @@ -4165,9 +4484,6 @@ impl serde::Serialize for FileOptions { if let Some(v) = self.py_generic_services.as_ref() { struct_ser.serialize_field("pyGenericServices", v)?; } - if let Some(v) = self.php_generic_services.as_ref() { - struct_ser.serialize_field("phpGenericServices", v)?; - } if let Some(v) = self.deprecated.as_ref() { struct_ser.serialize_field("deprecated", v)?; } @@ -4231,8 +4547,6 @@ impl<'de> serde::Deserialize<'de> for FileOptions { "javaGenericServices", "py_generic_services", "pyGenericServices", - "php_generic_services", - "phpGenericServices", "deprecated", "cc_enable_arenas", "ccEnableArenas", @@ -4267,7 +4581,6 @@ impl<'de> serde::Deserialize<'de> for FileOptions { CcGenericServices, JavaGenericServices, PyGenericServices, - PhpGenericServices, Deprecated, CcEnableArenas, ObjcClassPrefix, @@ -4310,7 +4623,6 @@ impl<'de> serde::Deserialize<'de> for FileOptions { "ccGenericServices" | "cc_generic_services" => Ok(GeneratedField::CcGenericServices), "javaGenericServices" | "java_generic_services" => Ok(GeneratedField::JavaGenericServices), "pyGenericServices" | "py_generic_services" => Ok(GeneratedField::PyGenericServices), - "phpGenericServices" | "php_generic_services" => Ok(GeneratedField::PhpGenericServices), "deprecated" => Ok(GeneratedField::Deprecated), "ccEnableArenas" | "cc_enable_arenas" => Ok(GeneratedField::CcEnableArenas), "objcClassPrefix" | "objc_class_prefix" => Ok(GeneratedField::ObjcClassPrefix), @@ -4351,7 +4663,6 @@ impl<'de> serde::Deserialize<'de> for FileOptions { let mut cc_generic_services__ = None; let mut java_generic_services__ = None; let mut py_generic_services__ = None; - let mut php_generic_services__ = None; let mut deprecated__ = None; let mut cc_enable_arenas__ = None; let mut objc_class_prefix__ = None; @@ -4425,12 +4736,6 @@ impl<'de> serde::Deserialize<'de> for FileOptions { } py_generic_services__ = map_.next_value()?; } - GeneratedField::PhpGenericServices => { - if php_generic_services__.is_some() { - return Err(serde::de::Error::duplicate_field("phpGenericServices")); - } - php_generic_services__ = map_.next_value()?; - } GeneratedField::Deprecated => { if deprecated__.is_some() { return Err(serde::de::Error::duplicate_field("deprecated")); @@ -4510,7 +4815,6 @@ impl<'de> serde::Deserialize<'de> for FileOptions { cc_generic_services: cc_generic_services__, java_generic_services: java_generic_services__, py_generic_services: py_generic_services__, - php_generic_services: php_generic_services__, deprecated: deprecated__, cc_enable_arenas: cc_enable_arenas__, objc_class_prefix: objc_class_prefix__, diff --git a/src/prost/proto_descriptor.bin b/src/prost/proto_descriptor.bin index e61b7875b928c81550a504da0286a304dc9021d1..a358d97cfaf1815164958c2503e296f8e42ad530 100644 GIT binary patch delta 25818 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