prost
prost copied to clipboard
prost-build 0.8.0 regression: `field_attribute` on a oneof field gets added to enum variants
Adding field attributes on oneof fields in prost-build 0.8.0 also adds the attributes to the enum variants. In this example, adding #[serde(flatten)] to TestMessage.some_field correctly adds the attribute to the TestMessage.some_field field of the struct, but also adds the attribute to each enum variant.
proto
syntax = "proto3";
package test;
message TestMessage {
oneof some_field {
string a_field = 1;
string b_field = 2;
}
}
build.rs
prost_build::Config::new()
.type_attribute("TestMessage", "#[derive(Serialize, Deserialize)]")
.type_attribute(
"TestMessage.some_field",
"#[derive(Serialize, Deserialize)]",
)
.field_attribute("TestMessage.some_field", "#[serde(flatten)]")
.compile_protos(&vec!["./protos/test.proto"], &["./protos/"])
.expect("prost error");
Outputs:
#[derive(Serialize, Deserialize)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct TestMessage {
#[prost(oneof="test_message::SomeField", tags="1, 2")]
#[serde(flatten)]
pub some_field: ::core::option::Option<test_message::SomeField>,
}
/// Nested message and enum types in `TestMessage`.
pub mod test_message {
#[derive(Serialize, Deserialize)]
#[derive(Clone, PartialEq, ::prost::Oneof)]
pub enum SomeField {
#[prost(string, tag="1")]
#[serde(flatten)]
AField(::prost::alloc::string::String),
#[prost(string, tag="2")]
#[serde(flatten)]
BField(::prost::alloc::string::String),
}
}
Notice the extra #[serde(flatten)] on each variant. This results in unknown serde variant attribute flatten since serde macro gets wrongly added to the enum variants.
Fixed in #522
This issue does not appear to be fixed. It still happens to me in master.
Is this an example of the same issue:
syntax="proto3";
package api;
message Init {
string msg_id = 1;
message SetOs {
enum OS {
OS_UNKNOWN = 0;
OS_WIN = 1;
OS_MAC = 2;
}
OS os_type = 2;
}
oneof Command {
SetOs os_cmd = 3;
}
}
when I use the following code (build.rs)
let mut config = prost_build::Config::new();
config.type_attribute(".", "#[derive(serde::Deserialize, serde::Serialize)]");
config.field_attribute(".api.Init.SetOs", "#[serde(default)]");
config.compile_protos(&["test_enum.proto"], &["../Proto"])
Then the variants of the enum also get attribute #[serde(default)].
pub mod init {
// ...
pub mod set_os {
// ...
#[repr(i32)]
pub enum Os {
#[serde(default)]
Unknown = 0,
#[serde(default)]
Win = 1,
#[serde(default)]
Mac = 2,
}
impl Os {
hello, this is still an issue. Is there any update on this?
@jszwec This issue needs someone to take the lead, finds a good solution and submits a PR. Feel free to take that role.