Skip to content

Commit acb7e5d

Browse files
committed
fix: boxed oneof field
fix tokio-rs#1159 Signed-off-by: xxchan <[email protected]>
1 parent 56b9602 commit acb7e5d

File tree

5 files changed

+22
-11
lines changed

5 files changed

+22
-11
lines changed

prost-build/src/code_generator.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -639,21 +639,21 @@ impl CodeGenerator<'_> {
639639

640640
self.push_indent();
641641
let ty_tag = self.field_type_tag(&field.descriptor);
642-
self.buf.push_str(&format!(
643-
"#[prost({}, tag=\"{}\")]\n",
644-
ty_tag,
645-
field.descriptor.number()
646-
));
647-
self.append_field_attributes(&oneof_name, field.descriptor.name());
648-
649-
self.push_indent();
650-
let ty = self.resolve_type(&field.descriptor, fq_message_name);
651-
652642
let boxed = self.boxed(
653643
&field.descriptor,
654644
fq_message_name,
655645
Some(oneof.descriptor.name()),
656646
);
647+
self.buf.push_str(&format!("#[prost({}", ty_tag));
648+
if boxed {
649+
self.buf.push_str(", boxed");
650+
}
651+
self.buf
652+
.push_str(&format!(", tag=\"{}\")]\n", field.descriptor.number()));
653+
self.append_field_attributes(&oneof_name, field.descriptor.name());
654+
655+
self.push_indent();
656+
let ty = self.resolve_type(&field.descriptor, fq_message_name);
657657

658658
debug!(
659659
" oneof: {:?}, type: {:?}, boxed: {}",

prost-derive/src/field/oneof.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use proc_macro2::TokenStream;
33
use quote::quote;
44
use syn::{parse_str, Expr, ExprLit, Ident, Lit, Meta, MetaNameValue, Path};
55

6-
use crate::field::{set_option, tags_attr};
6+
use crate::field::{set_bool, set_option, tags_attr, word_attr};
77

88
#[derive(Clone)]
99
pub struct Field {
@@ -15,6 +15,8 @@ impl Field {
1515
pub fn new(attrs: &[Meta]) -> Result<Option<Field>, Error> {
1616
let mut ty = None;
1717
let mut tags = None;
18+
let mut boxed = false;
19+
1820
let mut unknown_attrs = Vec::new();
1921

2022
for attr in attrs {
@@ -34,6 +36,8 @@ impl Field {
3436
set_option(&mut ty, t, "duplicate oneof attribute")?;
3537
} else if let Some(t) = tags_attr(attr)? {
3638
set_option(&mut tags, t, "duplicate tags attributes")?;
39+
} else if word_attr("boxed", attr) {
40+
set_bool(&mut boxed, "duplicate boxed attribute")?;
3741
} else {
3842
unknown_attrs.push(attr);
3943
}

tests/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ fn main() {
169169

170170
prost_build::Config::new()
171171
.boxed("Foo.bar")
172+
.boxed("Foo.oneof_field.box_qux")
172173
.compile_protos(&[src.join("boxed_field.proto")], includes)
173174
.unwrap();
174175

tests/src/boxed_field.proto

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ package boxed_field;
44

55
message Foo {
66
Bar bar = 1;
7+
oneof oneof_field {
8+
string baz = 2;
9+
Bar box_qux = 3;
10+
}
711
}
812

913
message Bar {

tests/src/boxed_field.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
include!(concat!(env!("OUT_DIR"), "/boxed_field.rs"));
2+
use foo::OneofField;
23

34
#[test]
45
/// Confirm `Foo::bar` is boxed by creating an instance
56
fn test_bar_is_boxed() {
67
use alloc::boxed::Box;
78
let _ = Foo {
89
bar: Some(Box::new(Bar {})),
10+
oneof_field: Some(OneofField::BoxQux(Box::new(Bar {}))),
911
};
1012
}

0 commit comments

Comments
 (0)