Skip to content

Commit

Permalink
fix bug in generic unions
Browse files Browse the repository at this point in the history
  • Loading branch information
David Renshaw committed Feb 11, 2017
1 parent fa644ee commit c248530
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
20 changes: 11 additions & 9 deletions src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ fn test_camel_to_snake_case() {
assert_eq!(camel_to_snake_case("uint32Id"), "uint32_id".to_string());
}

#[derive(PartialEq)]
#[derive(PartialEq, Clone)]
pub enum FormattedText {
Indent(Box<FormattedText>),
Branch(Vec<FormattedText>),
Expand Down Expand Up @@ -485,6 +485,7 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32,
let mut setter_interior = Vec::new();
let mut setter_param = "value".to_string();
let mut initter_interior = Vec::new();
let mut initn_interior = Vec::new();
let mut initter_params = Vec::new();

let discriminant_value = field.get_discriminant_value();
Expand All @@ -493,10 +494,11 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32,
Line(format!("self.builder.set_data_field::<u16>({}, {});",
discriminant_offset as usize,
discriminant_value as usize)));
initter_interior.push(
Line(format!("self.builder.set_data_field::<u16>({}, {});",
discriminant_offset as usize,
discriminant_value as usize)));
let init_discrim = Line(format!("self.builder.set_data_field::<u16>({}, {});",
discriminant_offset as usize,
discriminant_value as usize));
initter_interior.push(init_discrim.clone());
initn_interior.push(init_discrim);
}

let mut setter_generic_param = String::new();
Expand Down Expand Up @@ -554,15 +556,15 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32,
offset)));
initter_interior.push(Line(format!("self.builder.get_pointer_field({}).init_text(size)",
offset)));
initter_params.push("size : u32");
initter_params.push("size: u32");
(Some("text::Reader".to_string()), Some("text::Builder<'a>".to_string()))
}
type_::Data(()) => {
setter_interior.push(Line(format!("self.builder.get_pointer_field({}).set_data(value);",
offset)));
initter_interior.push(Line(format!("self.builder.get_pointer_field({}).init_data(size)",
offset)));
initter_params.push("size : u32");
initter_params.push("size: u32");
(Some("data::Reader".to_string()), Some("data::Builder<'a>".to_string()))
}
type_::List(ot1) => {
Expand All @@ -571,7 +573,7 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32,
Line(format!("::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field({}), value)",
offset)));

initter_params.push("size : u32");
initter_params.push("size: u32");
initter_interior.push(
Line(format!("::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field({}), size)", offset)));

Expand Down Expand Up @@ -631,12 +633,12 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32,
setter_interior.push(Line(format!("SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field({}), value)", offset)));
return_result = true;


let builder_type = try!(typ.type_string(gen, Leaf::Builder("'a")));

result.push(Line("#[inline]".to_string()));
result.push(Line(format!("pub fn initn_{}(self, length: u32) -> {} {{",
styled_name, builder_type)));
result.push(Indent(Box::new(Branch(initn_interior))));
result.push(Indent(Box::new(
Line(format!("::capnp::any_pointer::Builder::new(self.builder.get_pointer_field({})).initn_as(length)", offset)))));
result.push(Line("}".to_string()));
Expand Down
1 change: 1 addition & 0 deletions test/test.capnp
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ struct TestGenericsUnion(Foo, Bar) {
union {
foo1 @0 :Foo;
bar1 @1 :Bar;
foo2 @2 :Foo;
}
}

Expand Down
44 changes: 44 additions & 0 deletions test/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,50 @@ mod tests {
assert_eq!(bar_reader.get(0), 11);
}

#[test]
fn test_generic_union() {
use capnp::primitive_list;
use test_capnp::{test_generics_union, test_all_types};
let mut message = message::Builder::new_default();
{
let mut root: test_generics_union::Builder<test_all_types::Owned, primitive_list::Owned<u32>>
= message.init_root();
{
let mut bar = root.borrow().initn_bar1(10);
bar.set(5, 100);
}
assert!(!root.has_foo1());
assert!(root.has_bar1());
assert!(!root.has_foo2());

match root.borrow().which().unwrap() {
test_generics_union::Bar1(Ok(bar)) => {
assert_eq!(bar.len(), 10);
assert_eq!(bar.get(0), 0);
assert_eq!(bar.get(5), 100);
assert_eq!(bar.get(9), 0);
}
_ => panic!("expected Bar1"),
}

{
let mut foo = root.borrow().init_foo2();
foo.set_int32_field(37);
}

assert!(!root.has_foo1());
assert!(!root.has_bar1());
assert!(root.has_foo2());

match root.borrow().which().unwrap() {
test_generics_union::Foo2(Ok(foo)) => {
assert_eq!(foo.get_int32_field(), 37);
}
_ => panic!("expected Foo2"),
}
}
}

#[test]
fn test_union() {
use test_capnp::test_union;
Expand Down

0 comments on commit c248530

Please sign in to comment.