From a13340dc04210abc73f8b35915806172a12290e6 Mon Sep 17 00:00:00 2001 From: Michael Ward Date: Thu, 21 Mar 2024 13:51:37 -0500 Subject: [PATCH 1/6] [Rust] updated code generator to prevent rust warning for "ambiguous glob re-exports" --- rust/benches/car_benchmark.rs | 2 +- rust/tests/baseline_test.rs | 19 ++++++++---- rust/tests/big_endian_test.rs | 15 ++++++++-- rust/tests/extension_test.rs | 19 ++++++++---- rust/tests/issue_435_test.rs | 4 +++ rust/tests/issue_895_test.rs | 6 +--- rust/tests/issue_972_test.rs | 2 +- .../sbe/generation/rust/LibRsDef.java | 8 +---- .../sbe/generation/rust/MessageCoderDef.java | 3 +- .../sbe/generation/rust/RustGenerator.java | 30 ++++++++++++++----- 10 files changed, 74 insertions(+), 34 deletions(-) diff --git a/rust/benches/car_benchmark.rs b/rust/benches/car_benchmark.rs index 92b964147a..06b542452a 100644 --- a/rust/benches/car_benchmark.rs +++ b/rust/benches/car_benchmark.rs @@ -1,6 +1,6 @@ +use car_codec::encoder::*; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use examples_uk_co_real_logic_sbe_benchmarks::*; -use car_codec::encoder::*; const MANUFACTURER: &[u8] = b"MANUFACTURER"; const MODEL: &[u8] = b"MODEL"; diff --git a/rust/tests/baseline_test.rs b/rust/tests/baseline_test.rs index bff75170c4..58a8503d20 100644 --- a/rust/tests/baseline_test.rs +++ b/rust/tests/baseline_test.rs @@ -1,8 +1,17 @@ -use std::fs::File; -use std::io::prelude::*; - -use examples_baseline::*; -use car_codec::encoder::*; +use examples_baseline::{ + boolean_type::BooleanType, + boost_type::BoostType, + car_codec::{ + encoder::{AccelerationEncoder, FuelFiguresEncoder, PerformanceFiguresEncoder}, + *, + }, + message_header_codec, + message_header_codec::MessageHeaderDecoder, + model::Model, + optional_extras::OptionalExtras, + Encoder, ReadBuf, SbeResult, WriteBuf, +}; +use std::{fs::File, io::prelude::*}; fn read_sbe_file_generated_from_java_example() -> std::io::Result> { // Generated by the generateCarExampleDataFile gradle task. diff --git a/rust/tests/big_endian_test.rs b/rust/tests/big_endian_test.rs index a5a749c94a..aabea63ce2 100644 --- a/rust/tests/big_endian_test.rs +++ b/rust/tests/big_endian_test.rs @@ -1,5 +1,16 @@ -use baseline_bigendian::*; -use car_codec::encoder::*; +use baseline_bigendian::{ + boolean_type::BooleanType, + boost_type::BoostType, + car_codec::{ + encoder::{AccelerationEncoder, FuelFiguresEncoder, PerformanceFiguresEncoder}, + *, + }, + message_header_codec, + message_header_codec::MessageHeaderDecoder, + model::Model, + optional_extras::OptionalExtras, + Encoder, ReadBuf, SbeResult, WriteBuf, +}; #[test] fn big_endian_baseline_example() -> SbeResult<()> { diff --git a/rust/tests/extension_test.rs b/rust/tests/extension_test.rs index 07c81e9fb7..072b9b8baa 100644 --- a/rust/tests/extension_test.rs +++ b/rust/tests/extension_test.rs @@ -1,8 +1,17 @@ -use std::fs::File; -use std::io::prelude::*; - -use examples_extension::*; -use car_codec::encoder::*; +use examples_extension::{ + boolean_type::BooleanType, + boost_type::BoostType, + car_codec::{ + encoder::{AccelerationEncoder, FuelFiguresEncoder, PerformanceFiguresEncoder}, + *, + }, + message_header_codec, + message_header_codec::MessageHeaderDecoder, + model::Model, + optional_extras::OptionalExtras, + Encoder, ReadBuf, SbeResult, WriteBuf, +}; +use std::{fs::File, io::prelude::*}; fn read_sbe_file_generated_from_java_example() -> std::io::Result> { // Generated by the generateCarExampleDataFile gradle task. diff --git a/rust/tests/issue_435_test.rs b/rust/tests/issue_435_test.rs index 87bd9a075e..8ac9ce8a50 100644 --- a/rust/tests/issue_435_test.rs +++ b/rust/tests/issue_435_test.rs @@ -1,4 +1,8 @@ use ::issue_435::*; +use issue_435::{ + enum_ref::EnumRef, issue_435_codec::*, message_header_codec::MessageHeaderDecoder, + set_ref::SetRef, +}; fn create_encoder(buffer: &mut Vec) -> Issue435Encoder { let issue_435 = Issue435Encoder::default().wrap( diff --git a/rust/tests/issue_895_test.rs b/rust/tests/issue_895_test.rs index dd9b19fa04..96968d2459 100644 --- a/rust/tests/issue_895_test.rs +++ b/rust/tests/issue_895_test.rs @@ -1,8 +1,4 @@ -use issue_895::{ - issue_895_codec::{decoder::Issue895Decoder, encoder::Issue895Encoder}, - MessageHeaderDecoder, ReadBuf, SbeResult, WriteBuf, ENCODED_LENGTH, SBE_BLOCK_LENGTH, - SBE_SCHEMA_ID, SBE_SCHEMA_VERSION, SBE_TEMPLATE_ID, -}; +use issue_895::{issue_895_codec::*, message_header_codec::*, *}; fn create_encoder(buffer: &mut Vec) -> Issue895Encoder { let issue_895 = diff --git a/rust/tests/issue_972_test.rs b/rust/tests/issue_972_test.rs index bc3a938247..2cbab324d0 100644 --- a/rust/tests/issue_972_test.rs +++ b/rust/tests/issue_972_test.rs @@ -1,4 +1,4 @@ -use issue_972::*; +use issue_972::{issue_972_codec::*, message_header_codec::MessageHeaderDecoder, *}; fn create_encoder(buffer: &mut Vec) -> Issue972Encoder { let issue_972 = Issue972Encoder::default().wrap( diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java index a51b2746da..3c5ae1542d 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java @@ -78,13 +78,6 @@ void generate() throws IOException } indent(libRs, 0, "\n"); - // add re-export of modules - for (final String module : modules) - { - indent(libRs, 0, "pub use crate::%s::*;\n", toLowerSnakeCase(module)); - } - indent(libRs, 0, "\n"); - generateSbeErrorEnum(libRs); generateEitherEnum(libRs); @@ -163,6 +156,7 @@ static void generateReadBuf(final Appendable writer, final ByteOrder byteOrder) indent(writer, 0, "}\n"); // impl ReadBuf ... + indent(writer, 0, "#[allow(dead_code)]\n"); indent(writer, 0, "impl<%s> %s<%s> {\n", BUF_LIFETIME, READ_BUF_TYPE, BUF_LIFETIME); indent(writer, 1, "#[inline]\n"); indent(writer, 1, "pub fn new(data: &%s [u8]) -> Self {\n", BUF_LIFETIME); diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/MessageCoderDef.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/MessageCoderDef.java index 00c9ac03f6..dbe6fabc8f 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/MessageCoderDef.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/MessageCoderDef.java @@ -63,7 +63,8 @@ void generate( final List varData) throws IOException { indent(sb, 0, "pub mod %s {\n", codecType.toString().toLowerCase()); - indent(sb, 1, "use super::*;\n\n"); + indent(sb, 1, "use super::*;\n"); + indent(sb, 1, "use message_header_codec::*;\n\n"); // i.e. Decoder or Encoder final String msgTypeName = formatStructName(msgToken.name()) + codecType.name(); 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 d0067d836c..6569599993 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 @@ -449,7 +449,9 @@ private static void generateEnumEncoder( final String name) throws IOException { final String referencedName = typeToken.referencedName(); - final String enumType = formatStructName(referencedName == null ? typeToken.name() : referencedName); + final String enumType = format("%s::%s", + toLowerSnakeCase(referencedName == null ? typeToken.name() : referencedName), + formatStructName(referencedName == null ? typeToken.name() : referencedName)); if (fieldToken.isConstantEncoding()) { @@ -479,7 +481,10 @@ private static void generateBitSetEncoder( { final Encoding encoding = bitsetToken.encoding(); final String rustPrimitiveType = rustTypeName(encoding.primitiveType()); - final String structTypeName = formatStructName(bitsetToken.applicableTypeName()); + final String referencedName = bitsetToken.referencedName(); + final String structTypeName = format("%s::%s", + toLowerSnakeCase(referencedName == null ? bitsetToken.name() : referencedName), + formatStructName(bitsetToken.applicableTypeName())); indent(sb, level, "#[inline]\n"); indent(sb, level, "pub fn %s(&mut self, value: %s) {\n", formatFunctionName(name), structTypeName); @@ -496,7 +501,9 @@ private static void generateCompositeEncoder( final String name) throws IOException { final String encoderName = toLowerSnakeCase(encoderName(name)); - final String encoderTypeName = encoderName(formatStructName(typeToken.applicableTypeName())); + final String encoderTypeName = format("%s::%s", + codecModName(typeToken.referencedName() == null ? typeToken.name() : typeToken.referencedName()), + encoderName(formatStructName(typeToken.applicableTypeName()))); indent(sb, level, "/// COMPOSITE ENCODER\n"); indent(sb, level, "#[inline]\n"); indent(sb, level, "pub fn %s(self) -> %2$s {\n", @@ -556,7 +563,10 @@ private static void generateCompositeDecoder( final String name) throws IOException { final String decoderName = toLowerSnakeCase(decoderName(name)); - final String decoderTypeName = decoderName(formatStructName(typeToken.applicableTypeName())); + final String referencedName = typeToken.referencedName(); + final String decoderTypeName = format("%s::%s", + codecModName(referencedName == null ? typeToken.name() : referencedName), + decoderName(formatStructName(typeToken.applicableTypeName()))); indent(sb, level, "/// COMPOSITE DECODER\n"); indent(sb, level, "#[inline]\n"); if (fieldToken.version() > 0) @@ -575,7 +585,7 @@ private static void generateCompositeDecoder( } else { - indent(sb, level, "pub fn %s(self) -> %2$s {\n", + indent(sb, level, "pub fn %s(self) -> %s {\n", decoderName, decoderTypeName); @@ -593,7 +603,11 @@ private static void generateBitSetDecoder( { final Encoding encoding = bitsetToken.encoding(); final String rustPrimitiveType = rustTypeName(encoding.primitiveType()); - final String structTypeName = formatStructName(bitsetToken.applicableTypeName()); + final String referencedName = bitsetToken.referencedName(); + final String structTypeName = format("%s::%s", + toLowerSnakeCase(referencedName == null ? bitsetToken.name() : referencedName), + formatStructName(bitsetToken.applicableTypeName())); + indent(sb, level, "/// BIT SET DECODER\n"); indent(sb, level, "#[inline]\n"); indent(sb, level, "pub fn %s(&self) -> %s {\n", formatFunctionName(name), structTypeName); @@ -834,7 +848,9 @@ private static void generateEnumDecoder( final String name) throws IOException { final String referencedName = typeToken.referencedName(); - final String enumType = formatStructName(referencedName == null ? typeToken.name() : referencedName); + final String enumType = format("%s::%s", + toLowerSnakeCase(referencedName == null ? typeToken.name() : referencedName), + formatStructName(referencedName == null ? typeToken.name() : referencedName)); if (fieldToken.isConstantEncoding()) { From 15d71d3e04bbb10ae89ee089077f7a0cd401b72e Mon Sep 17 00:00:00 2001 From: Michael Ward Date: Thu, 4 Apr 2024 17:47:48 -0500 Subject: [PATCH 2/6] [Rust] defined new trait 'ActingVersion' --- .../sbe/generation/rust/LibRsDef.java | 20 +++-- .../sbe/generation/rust/MessageCoderDef.java | 4 +- .../sbe/generation/rust/RustGenerator.java | 87 ++++++++++++------- .../sbe/generation/rust/SubGroup.java | 14 ++- 4 files changed, 84 insertions(+), 41 deletions(-) diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java index 3c5ae1542d..eb9d9530a9 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java @@ -35,19 +35,23 @@ class LibRsDef { private final RustOutputManager outputManager; private final ByteOrder byteOrder; + private final String schemaVersionType; /** * Create a new 'lib.rs' for the library being generated * - * @param outputManager for generating the codecs to. - * @param byteOrder for the Encoding. + * @param outputManager for generating the codecs to. + * @param byteOrder for the Encoding. + * @param schemaVersionType for acting_version type */ LibRsDef( - final RustOutputManager outputManager, - final ByteOrder byteOrder) + final RustOutputManager outputManager, + final ByteOrder byteOrder, + final String schemaVersionType) { this.outputManager = outputManager; this.byteOrder = byteOrder; + this.schemaVersionType = schemaVersionType; } void generate() throws IOException @@ -82,7 +86,7 @@ void generate() throws IOException generateEitherEnum(libRs); generateEncoderTraits(libRs); - generateDecoderTraits(libRs); + generateDecoderTraits(schemaVersionType, libRs); generateReadBuf(libRs, byteOrder); generateWriteBuf(libRs, byteOrder); @@ -101,8 +105,12 @@ static void generateEncoderTraits(final Writer writer) throws IOException indent(writer, 0, "}\n\n"); } - static void generateDecoderTraits(final Writer writer) throws IOException + static void generateDecoderTraits( final String schemaVersionType, final Writer writer) throws IOException { + indent(writer, 0, "pub trait ActingVersion {\n"); + indent(writer, 1, "fn acting_version(&self) -> %s;\n", schemaVersionType); + indent(writer, 0, "}\n\n"); + indent(writer, 0, "pub trait Reader<'a>: Sized {\n"); indent(writer, 1, "fn get_buf(&self) -> &ReadBuf<'a>;\n"); indent(writer, 0, "}\n\n"); diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/MessageCoderDef.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/MessageCoderDef.java index dbe6fabc8f..67c37f22fd 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/MessageCoderDef.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/MessageCoderDef.java @@ -76,7 +76,7 @@ void generate( } else { - RustGenerator.appendImplDecoderTrait(sb, msgTypeName); + RustGenerator.appendImplDecoderTrait(schemaVersionType(), sb, msgTypeName); } RustGenerator.appendImplWithLifetimeHeader(sb, msgTypeName); // impl start @@ -92,7 +92,7 @@ void generate( appendMessageHeaderDecoderFn(sb); RustGenerator.generateDecoderFields(sb, fields, 2); - RustGenerator.generateDecoderGroups(sb, groups, 2, this); + RustGenerator.generateDecoderGroups(schemaVersionType(), sb, groups, 2, this); RustGenerator.generateDecoderVarData(sb, varData, 2, false); } else 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 6569599993..8e02e03bd0 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 @@ -127,11 +127,11 @@ public void generate() throws IOException } // lib.rs - final LibRsDef libRsDef = new LibRsDef(outputManager, ir.byteOrder()); + final LibRsDef libRsDef = new LibRsDef(outputManager, ir.byteOrder(), schemaVersionType()); generateEnums(ir, outputManager); generateBitSets(ir, outputManager); - generateComposites(ir, outputManager); + generateComposites(schemaVersionType(), ir, outputManager); for (final List tokens : ir.messages()) { @@ -428,6 +428,7 @@ private static void generatePrimitiveEncoder( indent(sb, level, "/// - semanticType: %s\n", encoding.semanticType()); indent(sb, level, "/// - encodedOffset: %d\n", typeToken.offset()); indent(sb, level, "/// - encodedLength: %d\n", typeToken.encodedLength()); + indent(sb, level, "/// - version: %d\n", typeToken.version()); indent(sb, level, "#[inline]\n"); indent(sb, level, "pub fn %s(&mut self, value: %s) {\n", formatFunctionName(name), @@ -575,7 +576,7 @@ private static void generateCompositeDecoder( decoderName, decoderTypeName); - indent(sb, level + 1, "if self.acting_version > 0 && self.acting_version < %d {\n", fieldToken.version()); + indent(sb, level + 1, "if self.acting_version() < %d {\n", fieldToken.version()); indent(sb, level + 2, "return Either::Left(self);\n"); indent(sb, level + 1, "}\n\n"); @@ -613,7 +614,7 @@ private static void generateBitSetDecoder( if (bitsetToken.version() > 0) { - indent(sb, level + 1, "if self.acting_version > 0 && self.acting_version < %d {\n", bitsetToken.version()); + indent(sb, level + 1, "if self.acting_version() < %d {\n", bitsetToken.version()); indent(sb, level + 2, "return %s::default();\n", structTypeName); indent(sb, level + 1, "}\n\n"); } @@ -673,7 +674,7 @@ private static void generatePrimitiveArrayDecoder( if (fieldToken.version() > 0) { - indent(sb, level + 1, "if self.acting_version > 0 && self.acting_version < %d {\n", fieldToken.version()); + indent(sb, level + 1, "if self.acting_version() < %d {\n", fieldToken.version()); indent(sb, level + 2, "return [%s; %d];\n", encoding.applicableNullValue(), arrayLength); indent(sb, level + 1, "}\n\n"); } @@ -827,7 +828,7 @@ private static void generatePrimitiveRequiredDecoder( if (fieldToken.version() > 0) { - indent(sb, level + 1, "if self.acting_version > 0 && self.acting_version < %d {\n", fieldToken.version()); + indent(sb, level + 1, "if self.acting_version() < %d {\n", fieldToken.version()); indent(sb, level + 2, "return %s;\n", generateRustLiteral(encoding.primitiveType(), encoding.applicableNullValue().toString())); indent(sb, level + 1, "}\n\n"); @@ -876,7 +877,7 @@ private static void generateEnumDecoder( if (fieldToken.version() > 0) { - indent(sb, level + 1, "if self.acting_version < %d {\n", fieldToken.version()); + indent(sb, level + 1, "if self.acting_version() < %d {\n", fieldToken.version()); indent(sb, level + 2, "return %s::default();\n", enumType); indent(sb, level + 1, "}\n\n"); } @@ -889,10 +890,11 @@ private static void generateEnumDecoder( } static void generateDecoderGroups( - final StringBuilder sb, - final List tokens, - final int level, - final ParentDef parentDef) throws IOException + final String schemaVersionType, + final StringBuilder sb, + final List tokens, + final int level, + final ParentDef parentDef) throws IOException { for (int i = 0, size = tokens.size(); i < size; i++) { @@ -936,7 +938,7 @@ static void generateDecoderGroups( indent(sb, level, "pub fn %s(self) -> Option<%2$s> {\n", formatFunctionName(groupName), groupName); - indent(sb, level + 1, "if self.acting_version < %d {\n", groupToken.version()); + indent(sb, level + 1, "if self.acting_version() < %d {\n", groupToken.version()); indent(sb, level + 2, "return None;\n"); indent(sb, level + 1, "}\n\n"); @@ -952,7 +954,7 @@ static void generateDecoderGroups( indent(sb, level, "}\n\n"); final SubGroup subGroup = parentDef.addSubGroup(groupName, level, groupToken); - subGroup.generateDecoder(tokens, fields, groups, varData, index); + subGroup.generateDecoder(schemaVersionType, tokens, fields, groups, varData, index); } } @@ -984,7 +986,7 @@ static void generateDecoderVarData( { if (varDataToken.version() > 0) { - indent(sb, level + 1, "if self.acting_version > 0 && self.acting_version < %d {\n", + indent(sb, level + 1, "if self.acting_version() < %d {\n", varDataToken.version()); indent(sb, level + 2, "return (self.parent.as_ref().unwrap().get_limit(), 0);\n"); indent(sb, level + 1, "}\n\n"); @@ -1000,7 +1002,7 @@ static void generateDecoderVarData( { if (varDataToken.version() > 0) { - indent(sb, level + 1, "if self.acting_version > 0 && self.acting_version < %d {\n", + indent(sb, level + 1, "if self.acting_version() < %d {\n", varDataToken.version()); indent(sb, level + 2, "return (self.get_limit(), 0);\n"); indent(sb, level + 1, "}\n\n"); @@ -1020,7 +1022,7 @@ static void generateDecoderVarData( if (varDataToken.version() > 0) { - indent(sb, level + 1, "if self.acting_version > 0 && self.acting_version < %d {\n", + indent(sb, level + 1, "if self.acting_version() < %d {\n", varDataToken.version()); indent(sb, level + 2, "return &[] as &[u8];\n"); indent(sb, level + 1, "}\n\n"); @@ -1162,9 +1164,17 @@ static void appendImplEncoderTrait( } static void appendImplDecoderTrait( - final Appendable out, - final String typeName) throws IOException + final String schemaVersionType, + final Appendable out, + final String typeName) throws IOException { + indent(out, 1, "impl<%s> %s for %s {\n", BUF_LIFETIME, "ActingVersion", withLifetime(typeName)); + indent(out, 2, "#[inline]\n"); + indent(out, 2, "fn acting_version(&self) -> %s {\n", schemaVersionType); + indent(out, 3, "self.acting_version\n"); + indent(out, 2, "}\n"); + indent(out, 1, "}\n\n"); + indent(out, 1, "impl<%s> %s for %s {\n", BUF_LIFETIME, withLifetime("Reader"), withLifetime(typeName)); indent(out, 2, "#[inline]\n"); indent(out, 2, "fn get_buf(&self) -> &ReadBuf<'a> {\n"); @@ -1271,19 +1281,21 @@ private static void generateEnum( } private static void generateComposites( - final Ir ir, - final RustOutputManager outputManager) throws IOException + final String schemaVersionType, + final Ir ir, + final RustOutputManager outputManager) throws IOException { for (final List tokens : ir.types()) { if (!tokens.isEmpty() && tokens.get(0).signal() == Signal.BEGIN_COMPOSITE) { - generateComposite(tokens, outputManager); + generateComposite(schemaVersionType, tokens, outputManager); } } } private static void generateComposite( + final String schemaVersionType, final List tokens, final RustOutputManager outputManager) throws IOException { @@ -1306,7 +1318,7 @@ private static void generateComposite( generateCompositeEncoder(tokens, encoderName(compositeName), out); indent(out, 0, "\n"); - generateCompositeDecoder(tokens, decoderName(compositeName), out); + generateCompositeDecoder(schemaVersionType, tokens, decoderName(compositeName), out); } } @@ -1350,12 +1362,22 @@ static void appendImplEncoderForComposite( } static void appendImplReaderForComposite( + final String schemaVersionType, + final int version, final Appendable out, final int level, final String name) throws IOException { + indent(out, level, "impl<'a, P> ActingVersion for %s

where P: Reader<'a> + ActingVersion + Default {\n", name); + indent(out, level + 1, "#[inline]\n"); + indent(out, level + 1, "fn acting_version(&self) -> %s {\n", schemaVersionType); + indent(out, level + 2, "self.parent.as_ref().unwrap().acting_version()\n"); + indent(out, level + 1, "}\n"); + indent(out, level, "}\n\n"); + // impl Reader... - indent(out, level, "impl<'a, P> Reader<'a> for %s

where P: Reader<'a> + Default {\n", name); + indent(out, level, "impl<'a, P> Reader<'a> for %s

where P: Reader<'a> %s+ Default {\n", + name, version > 0 ? "+ ActingVersion " : ""); indent(out, level + 1, "#[inline]\n"); indent(out, level + 1, "fn get_buf(&self) -> &ReadBuf<'a> {\n"); indent(out, level + 2, "self.parent.as_ref().expect(\"parent missing\").get_buf()\n"); @@ -1364,14 +1386,16 @@ static void appendImplReaderForComposite( } static void appendImplDecoderForComposite( - final Appendable out, - final int level, - final String name) throws IOException + final String schemaVersionType, + final int version, + final Appendable out, + final int level, + final String name) throws IOException { - appendImplReaderForComposite(out, level, name); + appendImplReaderForComposite(schemaVersionType, version, out, level, name); // impl Decoder... - indent(out, level, "impl<'a, P> Decoder<'a> for %s

where P: Decoder<'a> + Default {\n", name); + indent(out, level, "impl<'a, P> Decoder<'a> for %s

where P: Decoder<'a> + ActingVersion + Default {\n", name); indent(out, level + 1, "#[inline]\n"); indent(out, level + 1, "fn get_limit(&self) -> usize {\n"); indent(out, level + 2, "self.parent.as_ref().expect(\"parent missing\").get_limit()\n"); @@ -1447,6 +1471,7 @@ private static void generateCompositeEncoder( } private static void generateCompositeDecoder( + final String schemaVersionType, final List tokens, final String decoderName, final Writer out) throws IOException @@ -1460,10 +1485,12 @@ private static void generateCompositeDecoder( indent(out, 2, "offset: usize,\n"); indent(out, 1, "}\n\n"); - appendImplReaderForComposite(out, 1, decoderName); + final int version = tokens.stream().findFirst().get().version(); + appendImplReaderForComposite(schemaVersionType, version, out, 1, decoderName); // impl<'a, P> start - indent(out, 1, "impl<'a, P> %s

where P: Reader<'a> + Default {\n", decoderName); + indent(out, 1, "impl<'a, P> %s

where P: Reader<'a> %s+ Default {\n", + decoderName, version > 0 ? "+ ActingVersion " : ""); indent(out, 2, "pub fn wrap(mut self, parent: P, offset: usize) -> Self {\n"); indent(out, 3, "self.parent = Some(parent);\n"); indent(out, 3, "self.offset = offset;\n"); diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/SubGroup.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/SubGroup.java index 6407220065..d7a6123ec9 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/SubGroup.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/SubGroup.java @@ -140,6 +140,7 @@ void generateEncoder( } void generateDecoder( + final String schemaVersionType, final List tokens, final List fields, final List groups, @@ -162,10 +163,11 @@ void generateDecoder( indent(sb, level, "offset: usize,\n"); indent(sb, level - 1, "}\n\n"); - RustGenerator.appendImplDecoderForComposite(sb, level - 1, name); + final int version = tokens.stream().findFirst().get().version(); + RustGenerator.appendImplDecoderForComposite(schemaVersionType, version, sb, level - 1, name); // define impl... - indent(sb, level - 1, "impl<'a, P> %s

where P: Decoder<'a> + Default {\n", name); + indent(sb, level - 1, "impl<'a, P> %s

where P: Decoder<'a> + ActingVersion + Default {\n", name); final int dimensionHeaderSize = tokens.get(index).encodedLength(); @@ -197,6 +199,12 @@ void generateDecoder( indent(sb, level + 1, "self.parent.take().ok_or(SbeErr::ParentNotSet)\n"); indent(sb, level, "}\n\n"); + // acting_version fn... + indent(sb, level, "#[inline]\n"); + indent(sb, level, "pub fn acting_version(&mut self) -> %s {\n", schemaVersionType); + indent(sb, level + 1, "self.parent.as_ref().unwrap().acting_version()\n"); + indent(sb, level, "}\n\n"); + // count function indent(sb, level, "#[inline]\n"); indent(sb, level, "pub fn count(&self) -> %s {\n", rustTypeName(numInGroupPrimitiveType)); @@ -221,7 +229,7 @@ void generateDecoder( indent(sb, level, "}\n\n"); RustGenerator.generateDecoderFields(sb, fields, level); - RustGenerator.generateDecoderGroups(sb, groups, level, this); + RustGenerator.generateDecoderGroups(schemaVersionType, sb, groups, level, this); RustGenerator.generateDecoderVarData(sb, varData, level, true); indent(sb, level - 1, "}\n\n"); // close impl From e1c184a7c8101aa58145679863cf4a22d2e77fe3 Mon Sep 17 00:00:00 2001 From: Michael Ward Date: Thu, 4 Apr 2024 17:52:17 -0500 Subject: [PATCH 3/6] fixed code formatting issues --- .../sbe/generation/rust/LibRsDef.java | 8 ++-- .../sbe/generation/rust/RustGenerator.java | 38 ++++++++++--------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java index eb9d9530a9..2ed6eb1fcb 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/LibRsDef.java @@ -45,9 +45,9 @@ class LibRsDef * @param schemaVersionType for acting_version type */ LibRsDef( - final RustOutputManager outputManager, - final ByteOrder byteOrder, - final String schemaVersionType) + final RustOutputManager outputManager, + final ByteOrder byteOrder, + final String schemaVersionType) { this.outputManager = outputManager; this.byteOrder = byteOrder; @@ -105,7 +105,7 @@ static void generateEncoderTraits(final Writer writer) throws IOException indent(writer, 0, "}\n\n"); } - static void generateDecoderTraits( final String schemaVersionType, final Writer writer) throws IOException + static void generateDecoderTraits(final String schemaVersionType, final Writer writer) throws IOException { indent(writer, 0, "pub trait ActingVersion {\n"); indent(writer, 1, "fn acting_version(&self) -> %s;\n", schemaVersionType); 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 8e02e03bd0..1b53987098 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 @@ -890,11 +890,11 @@ private static void generateEnumDecoder( } static void generateDecoderGroups( - final String schemaVersionType, - final StringBuilder sb, - final List tokens, - final int level, - final ParentDef parentDef) throws IOException + final String schemaVersionType, + final StringBuilder sb, + final List tokens, + final int level, + final ParentDef parentDef) throws IOException { for (int i = 0, size = tokens.size(); i < size; i++) { @@ -1164,9 +1164,9 @@ static void appendImplEncoderTrait( } static void appendImplDecoderTrait( - final String schemaVersionType, - final Appendable out, - final String typeName) throws IOException + final String schemaVersionType, + final Appendable out, + final String typeName) throws IOException { indent(out, 1, "impl<%s> %s for %s {\n", BUF_LIFETIME, "ActingVersion", withLifetime(typeName)); indent(out, 2, "#[inline]\n"); @@ -1281,9 +1281,9 @@ private static void generateEnum( } private static void generateComposites( - final String schemaVersionType, - final Ir ir, - final RustOutputManager outputManager) throws IOException + final String schemaVersionType, + final Ir ir, + final RustOutputManager outputManager) throws IOException { for (final List tokens : ir.types()) { @@ -1368,7 +1368,8 @@ static void appendImplReaderForComposite( final int level, final String name) throws IOException { - indent(out, level, "impl<'a, P> ActingVersion for %s

where P: Reader<'a> + ActingVersion + Default {\n", name); + indent(out, level, "impl<'a, P> ActingVersion for %s

where P: Reader<'a> + ActingVersion + Default {\n", + name); indent(out, level + 1, "#[inline]\n"); indent(out, level + 1, "fn acting_version(&self) -> %s {\n", schemaVersionType); indent(out, level + 2, "self.parent.as_ref().unwrap().acting_version()\n"); @@ -1386,16 +1387,17 @@ static void appendImplReaderForComposite( } static void appendImplDecoderForComposite( - final String schemaVersionType, - final int version, - final Appendable out, - final int level, - final String name) throws IOException + final String schemaVersionType, + final int version, + final Appendable out, + final int level, + final String name) throws IOException { appendImplReaderForComposite(schemaVersionType, version, out, level, name); // impl Decoder... - indent(out, level, "impl<'a, P> Decoder<'a> for %s

where P: Decoder<'a> + ActingVersion + Default {\n", name); + indent(out, level, "impl<'a, P> Decoder<'a> for %s

where P: Decoder<'a> + ActingVersion + Default {\n", + name); indent(out, level + 1, "#[inline]\n"); indent(out, level + 1, "fn get_limit(&self) -> usize {\n"); indent(out, level + 2, "self.parent.as_ref().expect(\"parent missing\").get_limit()\n"); From ebec8ab6f7a1726f4449a54d650ef908e32ad5bc Mon Sep 17 00:00:00 2001 From: Michael Ward Date: Thu, 4 Apr 2024 18:12:54 -0500 Subject: [PATCH 4/6] [Rust] fixed benchmarks --- rust/benches/car_benchmark.rs | 16 +++++++++++----- rust/benches/md_benchmark.rs | 10 ++++++++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/rust/benches/car_benchmark.rs b/rust/benches/car_benchmark.rs index 06b542452a..5f78fff1e4 100644 --- a/rust/benches/car_benchmark.rs +++ b/rust/benches/car_benchmark.rs @@ -1,6 +1,12 @@ -use car_codec::encoder::*; use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use examples_uk_co_real_logic_sbe_benchmarks::*; +use examples_uk_co_real_logic_sbe_benchmarks::{ + boolean_type::BooleanType, + car_codec::{decoder::*, encoder::*}, + message_header_codec::MessageHeaderDecoder, + model::Model, + optional_extras::OptionalExtras, + *, +}; const MANUFACTURER: &[u8] = b"MANUFACTURER"; const MODEL: &[u8] = b"MODEL"; @@ -36,8 +42,8 @@ fn encode(state: &mut State) -> SbeResult { car.model_year(2005); car.serial_number(12345); car.available(BooleanType::T); - car.vehicle_code([97, 98, 99, 100, 101, 102]); // abcdef - car.some_numbers([0, 1, 2, 3, 4]); + car.vehicle_code(&[97, 98, 99, 100, 101, 102]); // abcdef + car.some_numbers(&[0, 1, 2, 3, 4]); extras.set_sports_pack(true); extras.set_sun_roof(true); @@ -46,7 +52,7 @@ fn encode(state: &mut State) -> SbeResult { let mut engine = car.engine_encoder(); engine.capacity(4200); engine.num_cylinders(8); - engine.manufacturer_code([97, 98, 99]); // abc + engine.manufacturer_code(&[97, 98, 99]); // abc car = engine.parent()?; fuel_figures = car.fuel_figures_encoder(3, fuel_figures); diff --git a/rust/benches/md_benchmark.rs b/rust/benches/md_benchmark.rs index ab7f4bf367..fd79f5759f 100644 --- a/rust/benches/md_benchmark.rs +++ b/rust/benches/md_benchmark.rs @@ -1,6 +1,12 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use examples_uk_co_real_logic_sbe_benchmarks_fix::*; -use market_data_incremental_refresh_trades_codec::encoder::*; +use examples_uk_co_real_logic_sbe_benchmarks_fix::{ + market_data_incremental_refresh_trades_codec::{*, encoder::*}, + match_event_indicator::*, + md_update_action::*, + message_header_codec::*, + side::*, + *, +}; struct State { buffer: Vec, From a088c5fe36c035242bffe2d176685b8767b6fb13 Mon Sep 17 00:00:00 2001 From: Michael Ward Date: Fri, 5 Apr 2024 09:14:24 -0500 Subject: [PATCH 5/6] [Rust] added test for issue 984 --- build.gradle | 1 + rust/Cargo.toml | 1 + rust/benches/md_benchmark.rs | 2 +- rust/tests/issue_435_test.rs | 3 +- rust/tests/issue_984_test.rs | 47 ++++++++++++++++++++++++ sbe-tool/src/test/resources/issue984.xml | 31 ++++++++++++++++ 6 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 rust/tests/issue_984_test.rs create mode 100644 sbe-tool/src/test/resources/issue984.xml diff --git a/build.gradle b/build.gradle index d932fa2ece..be16408906 100644 --- a/build.gradle +++ b/build.gradle @@ -588,6 +588,7 @@ tasks.register('generateRustTestCodecs', JavaExec) { args = ['sbe-tool/src/test/resources/issue435.xml', 'sbe-tool/src/test/resources/issue895.xml', 'sbe-tool/src/test/resources/issue972.xml', + 'sbe-tool/src/test/resources/issue984.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 6d47fc3746..4be04c957b 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -14,6 +14,7 @@ examples_uk_co_real_logic_sbe_benchmarks_fix = { path = "../generated/rust/uk_co issue_435 = { path = "../generated/rust/issue435" } issue_895 = { path = "../generated/rust/issue895" } issue_972 = { path = "../generated/rust/issue972" } +issue_984 = { path = "../generated/rust/issue984" } baseline_bigendian = { path = "../generated/rust/baseline-bigendian" } nested_composite_name = { path = "../generated/rust/nested-composite-name" } diff --git a/rust/benches/md_benchmark.rs b/rust/benches/md_benchmark.rs index fd79f5759f..025df09f4f 100644 --- a/rust/benches/md_benchmark.rs +++ b/rust/benches/md_benchmark.rs @@ -1,6 +1,6 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use examples_uk_co_real_logic_sbe_benchmarks_fix::{ - market_data_incremental_refresh_trades_codec::{*, encoder::*}, + market_data_incremental_refresh_trades_codec::{encoder::*, *}, match_event_indicator::*, md_update_action::*, message_header_codec::*, diff --git a/rust/tests/issue_435_test.rs b/rust/tests/issue_435_test.rs index 8ac9ce8a50..8664be42cd 100644 --- a/rust/tests/issue_435_test.rs +++ b/rust/tests/issue_435_test.rs @@ -1,7 +1,6 @@ -use ::issue_435::*; use issue_435::{ enum_ref::EnumRef, issue_435_codec::*, message_header_codec::MessageHeaderDecoder, - set_ref::SetRef, + set_ref::SetRef, *, }; fn create_encoder(buffer: &mut Vec) -> Issue435Encoder { diff --git a/rust/tests/issue_984_test.rs b/rust/tests/issue_984_test.rs new file mode 100644 index 0000000000..7ca0dcfc76 --- /dev/null +++ b/rust/tests/issue_984_test.rs @@ -0,0 +1,47 @@ +use issue_984::{ + message_header_codec::MessageHeaderDecoder, + simple_message_codec::{encoder::MyGroupEncoder, *}, + *, +}; + +fn create_encoder(buffer: &mut Vec) -> SimpleMessageEncoder { + let simple_msg = SimpleMessageEncoder::default().wrap( + WriteBuf::new(buffer.as_mut_slice()), + message_header_codec::ENCODED_LENGTH, + ); + let mut header = simple_msg.header(0); + header.parent().unwrap() +} + +#[test] +fn round_trip() -> SbeResult<()> { + // encode... + let mut buffer = vec![0u8; 256]; + let mut simple_msg_encoder = create_encoder(&mut buffer); + simple_msg_encoder.id(1985); + + let mut my_grp_encoder = simple_msg_encoder.my_group_encoder(1, MyGroupEncoder::default()); + my_grp_encoder.advance()?; + my_grp_encoder.f1(&[1, 2, 3, 4]); + my_grp_encoder.f2(&[1, 2, 3, 4, 5]); + my_grp_encoder.f3(&[1, 2, 3, 4, 5, 6]); + + // decode... + let buf = ReadBuf::new(buffer.as_slice()); + let header = MessageHeaderDecoder::default().wrap(buf, 0); + assert_eq!(SBE_BLOCK_LENGTH, header.block_length()); + assert_eq!(SBE_SCHEMA_VERSION, header.version()); + assert_eq!(SBE_TEMPLATE_ID, header.template_id()); + assert_eq!(SBE_SCHEMA_ID, header.schema_id()); + + let simple_msg_decoder = SimpleMessageDecoder::default().header(header); + assert_eq!(1985, simple_msg_decoder.id()); + let mut grp_decoder = simple_msg_decoder.my_group_decoder(); + assert_eq!(1, grp_decoder.count()); + grp_decoder.advance()?; + + assert_eq!([1, 2, 3, 4], grp_decoder.f1()); + assert_eq!([1, 2, 3, 4, 5], grp_decoder.f2()); + assert_eq!([1, 2, 3, 4, 5, 6], grp_decoder.f3()); + Ok(()) +} diff --git a/sbe-tool/src/test/resources/issue984.xml b/sbe-tool/src/test/resources/issue984.xml new file mode 100644 index 0000000000..bfbc961ace --- /dev/null +++ b/sbe-tool/src/test/resources/issue984.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From c63a66ba9a1c9befc952d14d33b9ebb55e180dc2 Mon Sep 17 00:00:00 2001 From: Michael Ward Date: Fri, 5 Apr 2024 13:48:37 -0500 Subject: [PATCH 6/6] [Rust] updated SubGroup.generateDecoder() to resolve unnecessary cast warning --- .../java/uk/co/real_logic/sbe/generation/rust/SubGroup.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/SubGroup.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/SubGroup.java index d7a6123ec9..d0b5abc433 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/SubGroup.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/SubGroup.java @@ -157,7 +157,7 @@ void generateDecoder( indent(sb, level - 1, "#[derive(Debug, Default)]\n"); indent(sb, level - 1, "pub struct %s

{\n", name); indent(sb, level, "parent: Option

,\n"); - indent(sb, level, "block_length: usize,\n"); + indent(sb, level, "block_length: %s,\n", rustTypeName(blockLengthPrimitiveType)); indent(sb, level, "count: %s,\n", rustTypeName(numInGroupPrimitiveType)); indent(sb, level, "index: usize,\n"); indent(sb, level, "offset: usize,\n"); @@ -177,7 +177,7 @@ void generateDecoder( indent(sb, level + 1, "mut parent: P,\n"); indent(sb, level, ") -> Self {\n"); indent(sb, level + 1, "let initial_offset = parent.get_limit();\n"); - indent(sb, level + 1, "let block_length = parent.get_buf().get_%s_at(initial_offset) as usize;\n", + indent(sb, level + 1, "let block_length = parent.get_buf().get_%s_at(initial_offset);\n", rustTypeName(blockLengthPrimitiveType)); indent(sb, level + 1, "let count = parent.get_buf().get_%s_at(initial_offset + %d);\n", rustTypeName(numInGroupPrimitiveType), numInGroupToken.offset());