Skip to content

Commit c85dd0b

Browse files
author
Vadim Platonov
committed
[Rust] Pad struct fields when needed
Fails on non-standard message header as it's currently generated separately.
1 parent 1f856e4 commit c85dd0b

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

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

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,9 +1399,24 @@ private static void generateSingleComposite(final List<Token> tokens, final Outp
13991399
}
14001400
}
14011401

1402+
private static final class RustStructField
1403+
{
1404+
final boolean isPub;
1405+
final String name;
1406+
final String value;
1407+
1408+
private RustStructField(boolean isPub, String name, String value) {
1409+
this.isPub = isPub;
1410+
this.name = name;
1411+
this.value = value;
1412+
}
1413+
}
1414+
14021415
private static void appendStructFields(final Appendable appendable, final List<NamedToken> namedTokens)
14031416
throws IOException
14041417
{
1418+
final List<RustStructField> fields = new ArrayList<>();
1419+
int totalSize = 0;
14051420
for (final NamedToken namedToken : namedTokens)
14061421
{
14071422
final Token typeToken = namedToken.typeToken();
@@ -1411,28 +1426,40 @@ private static void appendStructFields(final Appendable appendable, final List<N
14111426
}
14121427

14131428
final String propertyName = formatMethodName(namedToken.name());
1414-
indent(appendable).append("pub ").append(propertyName).append(":");
1429+
1430+
// need padding when field offsets imply gaps
1431+
final int offset = typeToken.offset();
1432+
if (offset != totalSize) {
1433+
final String value = getRustStaticArrayString("u8", offset - totalSize);
1434+
fields.add(new RustStructField(false, propertyName + "_padding", value));
1435+
}
1436+
totalSize += typeToken.encodedLength();
14151437

14161438
switch (typeToken.signal())
14171439
{
14181440
case ENCODING:
14191441
final String rustPrimitiveType = RustUtil.rustTypeName(typeToken.encoding().primitiveType());
14201442
final String rustFieldType = getRustTypeForPrimitivePossiblyArray(typeToken, rustPrimitiveType);
1421-
appendable.append(rustFieldType);
1443+
fields.add(new RustStructField(true, propertyName, rustFieldType));
14221444
break;
14231445

14241446
case BEGIN_ENUM:
14251447
case BEGIN_SET:
14261448
case BEGIN_COMPOSITE:
1427-
appendable.append(formatTypeName(typeToken.applicableTypeName()));
1449+
fields.add(new RustStructField(true, propertyName, formatTypeName(typeToken.applicableTypeName())));
14281450
break;
14291451

14301452
default:
14311453
throw new IllegalStateException(
14321454
format("Unsupported struct property from %s", typeToken.toString()));
14331455
}
14341456

1435-
appendable.append(",\n");
1457+
for (RustStructField field: fields) {
1458+
indent(appendable);
1459+
if (field.isPub) appendable.append("pub ");
1460+
appendable.append(field.name).append(":").append(field.value).append(",\n");
1461+
}
1462+
fields.clear();
14361463
}
14371464
}
14381465

@@ -1504,13 +1531,18 @@ private static void appendStructHeader(
15041531
appendable.append(format("pub struct %s {\n", structName));
15051532
}
15061533

1534+
private static String getRustStaticArrayString(final String rustPrimitiveType, final int length)
1535+
{
1536+
return format("[%s;%s]", rustPrimitiveType, length);
1537+
}
1538+
15071539
private static String getRustTypeForPrimitivePossiblyArray(
15081540
final Token encodingToken, final String rustPrimitiveType)
15091541
{
15101542
final String rustType;
15111543
if (encodingToken.arrayLength() > 1)
15121544
{
1513-
rustType = format("[%s;%s]", rustPrimitiveType, encodingToken.arrayLength());
1545+
rustType = getRustStaticArrayString(rustPrimitiveType, encodingToken.arrayLength());
15141546
}
15151547
else
15161548
{

sbe-tool/src/test/java/uk/co/real_logic/sbe/generation/rust/RustGeneratorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ private void assertRustBuildable(final String generatedRust, final Optional<Stri
234234
{
235235
Assume.assumeTrue(cargoExists());
236236
final File folder = writeCargoFolderWrapper(name.orElse("test"), generatedRust, folderRule.newFolder());
237-
assertTrue("Generated Rust should be buildable with cargo", cargoCheckInDirectory(folder));
237+
assertTrue(String.format("Generated Rust (%s) should be buildable with cargo", name), cargoCheckInDirectory(folder));
238238
}
239239

240240
private void assertSchemaInterpretableAsRust(final String localResourceSchema)

0 commit comments

Comments
 (0)