From c248530330162d1876e38f99bb85c70b7a7015a8 Mon Sep 17 00:00:00 2001 From: David Renshaw Date: Sat, 11 Feb 2017 08:52:08 -0500 Subject: [PATCH] fix bug in generic unions --- src/codegen.rs | 20 +++++++++++--------- test/test.capnp | 1 + test/test.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/codegen.rs b/src/codegen.rs index 1f08833..5554de7 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -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), Branch(Vec), @@ -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(); @@ -493,10 +494,11 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, Line(format!("self.builder.set_data_field::({}, {});", discriminant_offset as usize, discriminant_value as usize))); - initter_interior.push( - Line(format!("self.builder.set_data_field::({}, {});", - discriminant_offset as usize, - discriminant_value as usize))); + let init_discrim = Line(format!("self.builder.set_data_field::({}, {});", + 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(); @@ -554,7 +556,7 @@ 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(()) => { @@ -562,7 +564,7 @@ fn generate_setter(gen: &GeneratorContext, discriminant_offset: u32, 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) => { @@ -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))); @@ -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())); diff --git a/test/test.capnp b/test/test.capnp index d4ce77b..b927818 100644 --- a/test/test.capnp +++ b/test/test.capnp @@ -331,6 +331,7 @@ struct TestGenericsUnion(Foo, Bar) { union { foo1 @0 :Foo; bar1 @1 :Bar; + foo2 @2 :Foo; } } diff --git a/test/test.rs b/test/test.rs index 6737a52..cccf8d4 100644 --- a/test/test.rs +++ b/test/test.rs @@ -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> + = 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;