Skip to content

Commit 35d95aa

Browse files
authored
Merge pull request #679 from dm3/rust-field-offsets
Rust codec improvements - handle offsets, custom group size encoding
2 parents fb64c01 + 39e3947 commit 35d95aa

File tree

5 files changed

+609
-191
lines changed

5 files changed

+609
-191
lines changed

build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,9 +542,10 @@ task generateRustCarExample(type: JavaExec) {
542542
classpath = project(':sbe-all').sourceSets.main.runtimeClasspath
543543
systemProperties(
544544
'sbe.output.dir': 'rust/car_example/src',
545+
'sbe.xinclude.aware': 'true',
545546
'sbe.target.language': 'uk.co.real_logic.sbe.generation.rust.Rust',
546547
'sbe.target.namespace': 'car_example_generated_codec')
547-
args = ['sbe-tool/src/test/resources/example-schema.xml']
548+
args = ['sbe-samples/src/main/resources/example-schema.xml']
548549
}
549550

550551
task generateCarExampleDataFile(type: JavaExec) {

rust/car_example/src/main.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ impl std::convert::From<CodecErr> for IoError {
4545

4646
fn decode_car_and_assert_expected_content(buffer: &[u8]) -> CodecResult<()> {
4747
let (h, dec_fields) = start_decoding_car(&buffer).header()?;
48-
assert_eq!(49u16, h.block_length);
48+
assert_eq!(45u16, {h.block_length});
4949
assert_eq!(h.block_length as usize, ::std::mem::size_of::<CarFields>());
50-
assert_eq!(1u16, h.template_id);
51-
assert_eq!(1u16, h.schema_id);
52-
assert_eq!(0u16, h.version);
50+
assert_eq!(1u16, {h.template_id});
51+
assert_eq!(1u16, {h.schema_id});
52+
assert_eq!(0u16, {h.version});
5353
println!("Header read");
5454

5555
assert_eq!(Model::C, CarFields::discounted_model());
@@ -59,16 +59,16 @@ fn decode_car_and_assert_expected_content(buffer: &[u8]) -> CodecResult<()> {
5959
let mut found_fuel_figures = Vec::<FuelFigure>::with_capacity(EXPECTED_FUEL_FIGURES.len());
6060

6161
let (fields, dec_fuel_figures_header) = dec_fields.car_fields()?;
62-
assert_eq!(1234, fields.serial_number);
63-
assert_eq!(2013, fields.model_year);
64-
assert_eq!(BooleanType::T, fields.available);
65-
assert_eq!([97_i8, 98, 99, 100, 101, 102], fields.vehicle_code); // abcdef
66-
assert_eq!([0_u32, 1, 2, 3, 4], fields.some_numbers);
62+
assert_eq!(1234, {fields.serial_number});
63+
assert_eq!(2013, {fields.model_year});
64+
assert_eq!(BooleanType::T, {fields.available});
65+
assert_eq!([97_i8, 98, 99, 100, 101, 102], {fields.vehicle_code}); // abcdef
66+
assert_eq!([1, 2, 3, 4], {fields.some_numbers});
6767
assert_eq!(6, fields.extras.0);
6868
assert!(fields.extras.get_cruise_control());
6969
assert!(fields.extras.get_sports_pack());
7070
assert!(!fields.extras.get_sun_roof());
71-
assert_eq!(2000, fields.engine.capacity);
71+
assert_eq!(2000, {fields.engine.capacity});
7272
assert_eq!(4, fields.engine.num_cylinders);
7373
assert_eq!(BoostType::NITROUS, fields.engine.booster.boost_type);
7474
assert_eq!(200, fields.engine.booster.horse_power);
@@ -82,12 +82,12 @@ fn decode_car_and_assert_expected_content(buffer: &[u8]) -> CodecResult<()> {
8282
let (usage_description, next_step) = dec_usage_description.usage_description()?;
8383
let usage_str = std::str::from_utf8(usage_description).unwrap();
8484
println!("Fuel Figure: Speed: {0}, MPG: {1}, Usage: {2}",
85-
ff_fields.speed,
86-
ff_fields.mpg,
85+
{ff_fields.speed},
86+
{ff_fields.mpg},
8787
usage_str);
8888
found_fuel_figures.push(FuelFigure {
89-
speed: ff_fields.speed,
90-
mpg: ff_fields.mpg,
89+
speed: {ff_fields.speed},
90+
mpg: {ff_fields.mpg},
9191
usage_description: usage_str,
9292
});
9393
match next_step {
@@ -117,8 +117,8 @@ fn decode_car_and_assert_expected_content(buffer: &[u8]) -> CodecResult<()> {
117117
let (accel_slice, next_step) = dec_acceleration_header.acceleration_as_slice()?;
118118
for accel_fields in accel_slice {
119119
println!("Acceleration: MPH: {0}, Seconds: {1}",
120-
accel_fields.mph,
121-
accel_fields.seconds);
120+
{accel_fields.mph},
121+
{accel_fields.seconds});
122122
}
123123
match next_step {
124124
Either::Left(more_members) => dec_pf_members = more_members,
@@ -165,7 +165,7 @@ fn encode_car_from_scratch() -> CodecResult<Vec<u8>> {
165165
fields.available = BooleanType::T;
166166
fields.code = Model::A;
167167
fields.vehicle_code = [97_i8, 98, 99, 100, 101, 102]; // abcdef
168-
fields.some_numbers = [0_u32, 1, 2, 3, 4];
168+
fields.some_numbers = [1, 2, 3, 4];
169169
fields.extras = OptionalExtras::new();
170170
fields.extras.set_cruise_control(true)
171171
.set_sports_pack(true)
@@ -274,4 +274,4 @@ const EXPECTED_PERF_FIXTURES: &'static [PerfFigure] = &[PerfFigure {
274274
mph: 100,
275275
seconds: 11.8,
276276
}],
277-
}];
277+
}];

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustCodecType.java

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,18 @@ void appendDirectCodeMethods(
4444
final String methodName,
4545
final String representationType,
4646
final String nextCoderType,
47-
final int numBytes) throws IOException
47+
final int numBytes,
48+
final int trailingBytes) throws IOException
4849
{
4950
indent(appendable, 1, "pub fn %s(mut self) -> CodecResult<(&%s %s, %s)> {\n",
5051
methodName, DATA_LIFETIME, representationType, RustGenerator.withLifetime(nextCoderType));
5152
indent(appendable, 2, "let v = self.%s.read_type::<%s>(%s)?;\n",
5253
RustCodecType.Decoder.scratchProperty(), representationType, numBytes);
54+
if (trailingBytes > 0)
55+
{
56+
indent(appendable, 2, "self.%s.skip_bytes(%s)?;\n",
57+
RustCodecType.Decoder.scratchProperty(), trailingBytes);
58+
}
5359
indent(appendable, 2, "Ok((v, %s::wrap(self.%s)))\n",
5460
nextCoderType, RustCodecType.Decoder.scratchProperty());
5561
indent(appendable).append("}\n");
@@ -78,15 +84,20 @@ void appendDirectCodeMethods(
7884
final String methodName,
7985
final String representationType,
8086
final String nextCoderType,
81-
final int numBytes) throws IOException
87+
final int numBytes,
88+
final int trailingBytes) throws IOException
8289
{
8390
indent(appendable, 1, "\n/// Create a mutable struct reference overlaid atop the data buffer\n");
8491
indent(appendable, 1, "/// such that changes to the struct directly edit the buffer. \n");
8592
indent(appendable, 1, "/// Note that the initial content of the struct's fields may be garbage.\n");
8693
indent(appendable, 1, "pub fn %s(mut self) -> CodecResult<(&%s mut %s, %s)> {\n",
8794
methodName, DATA_LIFETIME, representationType, RustGenerator.withLifetime(nextCoderType));
88-
indent(appendable, 2, "let v = self.%s.writable_overlay::<%s>(%s)?;\n",
89-
RustCodecType.Encoder.scratchProperty(), representationType, numBytes);
95+
if (trailingBytes > 0)
96+
{
97+
indent(appendable, 2, "// add trailing bytes to extend the end position of the scratch buffer\n");
98+
}
99+
indent(appendable, 2, "let v = self.%s.writable_overlay::<%s>(%s+%s)?;\n",
100+
RustCodecType.Encoder.scratchProperty(), representationType, numBytes, trailingBytes);
90101
indent(appendable, 2, "Ok((v, %s::wrap(self.%s)))\n",
91102
nextCoderType, RustCodecType.Encoder.scratchProperty());
92103
indent(appendable).append("}\n\n");
@@ -97,6 +108,12 @@ void appendDirectCodeMethods(
97108
indent(appendable, 2)
98109
.append(format("self.%s.write_type::<%s>(t, %s)?;\n",
99110
RustCodecType.Encoder.scratchProperty(), representationType, numBytes));
111+
if (trailingBytes > 0)
112+
{
113+
indent(appendable, 2, "// fixed message length > sum of field lengths\n");
114+
indent(appendable, 2, "self.%s.skip_bytes(%s)?;\n",
115+
RustCodecType.Decoder.scratchProperty(), trailingBytes);
116+
}
100117
indent(appendable, 2).append(format("Ok(%s::wrap(self.%s))\n",
101118
nextCoderType, RustCodecType.Encoder.scratchProperty()));
102119
indent(appendable).append("}\n");
@@ -125,7 +142,8 @@ abstract void appendDirectCodeMethods(
125142
String methodName,
126143
String representationType,
127144
String nextCoderType,
128-
int numBytes) throws IOException;
145+
int numBytes,
146+
int trailingBytes) throws IOException;
129147

130148
abstract String gerund();
131149

@@ -175,7 +193,7 @@ String generateMessageHeaderCoder(
175193
appendScratchWrappingStruct(writer, headerCoderType);
176194
RustGenerator.appendImplWithLifetimeHeader(writer, headerCoderType);
177195
appendWrapMethod(writer, headerCoderType);
178-
appendDirectCodeMethods(writer, "header", messageHeaderRepresentation, topType, headerSize);
196+
appendDirectCodeMethods(writer, "header", messageHeaderRepresentation, topType, headerSize, 0);
179197
writer.append("}\n");
180198
}
181199

0 commit comments

Comments
 (0)