diff --git a/build.gradle b/build.gradle index a6f9f542b0..b349fe2528 100644 --- a/build.gradle +++ b/build.gradle @@ -677,6 +677,7 @@ tasks.register('generateRustTestCodecs', JavaExec) { 'sbe-tool/src/test/resources/issue987.xml', 'sbe-tool/src/test/resources/issue1028.xml', 'sbe-tool/src/test/resources/issue1057.xml', + 'sbe-tool/src/test/resources/issue1066.xml', 'sbe-tool/src/test/resources/fixed-sized-primitive-array-types.xml', 'sbe-tool/src/test/resources/example-bigendian-test-schema.xml', 'sbe-tool/src/test/resources/nested-composite-name.xml', diff --git a/rust/Cargo.toml b/rust/Cargo.toml index e09cacf21c..b48fd6ee55 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -18,6 +18,7 @@ issue_984 = { path = "../generated/rust/issue984" } issue_987 = { path = "../generated/rust/issue987" } issue_1028 = { path = "../generated/rust/issue1028" } issue_1057 = { path = "../generated/rust/issue1057" } +issue_1066 = { path = "../generated/rust/issue1066" } baseline_bigendian = { path = "../generated/rust/baseline-bigendian" } nested_composite_name = { path = "../generated/rust/nested-composite-name" } fixed_sized_primitive_array = { path = "../generated/rust/fixed_sized_primitive_array" } diff --git a/rust/tests/issue_1066_test.rs b/rust/tests/issue_1066_test.rs new file mode 100644 index 0000000000..43f7278ebf --- /dev/null +++ b/rust/tests/issue_1066_test.rs @@ -0,0 +1,40 @@ +use issue_1066::{ + issue_1066_codec, + issue_1066_codec::{Issue1066Decoder, Issue1066Encoder}, + *, +}; + +#[test] +fn decode_optional_primitive_field() { + let mut buffer = vec![0u8; 256]; + + // Create a message with `field` set. + let mut encoder = Issue1066Encoder::default().wrap( + WriteBuf::new(&mut buffer), + message_header_codec::ENCODED_LENGTH, + ); + encoder.field(10); + + // Drop encoder to drop the mut reference for the buffer. + drop(encoder); + + // Create a decoder for the message, but stating that the version is 1, instead of 2 + // which is the acting version for `field`. Thus, `field()` must return `None`. + let decoder = Issue1066Decoder::default().wrap( + ReadBuf::new(&mut buffer), + message_header_codec::ENCODED_LENGTH, + issue_1066_codec::SBE_BLOCK_LENGTH, + 1, + ); + assert!(decoder.field().is_none()); + + // Create a decoder for the message, but stating that the version is 1, instead of 2 + // which is the acting version for `field`. Thus, `field()` must return `None`. + let decoder = Issue1066Decoder::default().wrap( + ReadBuf::new(&mut buffer), + message_header_codec::ENCODED_LENGTH, + issue_1066_codec::SBE_BLOCK_LENGTH, + 2, + ); + assert_eq!(decoder.field(), Some(10)); +} diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java index 10d0219b33..746f18d022 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java @@ -894,6 +894,13 @@ private static void generatePrimitiveOptionalDecoder( formatFunctionName(name), rustPrimitiveType); + if (fieldToken.version() > 0) + { + indent(sb, level + 1, "if self.acting_version() < %d {\n", fieldToken.version()); + indent(sb, level + 2, "return None;\n"); + indent(sb, level + 1, "}\n\n"); + } + indent(sb, level + 1, "let value = self.get_buf().get_%s_at(self.%s);\n", rustPrimitiveType, getBufOffset(fieldToken)); diff --git a/sbe-tool/src/test/resources/issue1066.xml b/sbe-tool/src/test/resources/issue1066.xml new file mode 100644 index 0000000000..a24e45b030 --- /dev/null +++ b/sbe-tool/src/test/resources/issue1066.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + \ No newline at end of file