Skip to content

Commit f2c9b07

Browse files
author
Vadim Platonov
committed
[Rust] Generate custom message header with padding
1 parent 02437c8 commit f2c9b07

File tree

1 file changed

+72
-42
lines changed

1 file changed

+72
-42
lines changed

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

Lines changed: 72 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,15 +1405,21 @@ private static void generateSingleComposite(final List<Token> tokens, final Outp
14051405
private interface RustTypeDescriptor
14061406
{
14071407
String name();
1408-
String literal(String valueRep);
1408+
String literalValue(String valueRep);
1409+
1410+
default String defaultValue()
1411+
{
1412+
return "Default::default()";
1413+
}
14091414
}
14101415

14111416
private static final class RustArrayType implements RustTypeDescriptor
14121417
{
14131418
private final RustTypeDescriptor componentType;
14141419
private final int length;
14151420

1416-
private RustArrayType(RustTypeDescriptor component, int length) {
1421+
private RustArrayType(RustTypeDescriptor component, int length)
1422+
{
14171423
this.componentType = component;
14181424
this.length = length;
14191425
}
@@ -1425,7 +1431,7 @@ public String name()
14251431
}
14261432

14271433
@Override
1428-
public String literal(String valueRep)
1434+
public String literalValue(String valueRep)
14291435
{
14301436
return getRustStaticArrayString(valueRep + componentType.name(), length);
14311437
}
@@ -1435,7 +1441,8 @@ private static final class RustPrimitiveType implements RustTypeDescriptor
14351441
{
14361442
private final String name;
14371443

1438-
private RustPrimitiveType(String name) {
1444+
private RustPrimitiveType(String name)
1445+
{
14391446
this.name = name;
14401447
}
14411448

@@ -1446,7 +1453,7 @@ public String name()
14461453
}
14471454

14481455
@Override
1449-
public String literal(String valueRep)
1456+
public String literalValue(String valueRep)
14501457
{
14511458
return valueRep + name;
14521459
}
@@ -1456,7 +1463,8 @@ private static final class AnyRustType implements RustTypeDescriptor
14561463
{
14571464
private final String name;
14581465

1459-
private AnyRustType(String name) {
1466+
private AnyRustType(String name)
1467+
{
14601468
this.name = name;
14611469
}
14621470

@@ -1467,7 +1475,7 @@ public String name()
14671475
}
14681476

14691477
@Override
1470-
public String literal(String valueRep)
1478+
public String literalValue(String valueRep)
14711479
{
14721480
final String msg = String.format("Cannot produce a literal value %s of type %s!", valueRep, name);
14731481
throw new UnsupportedOperationException(msg);
@@ -1502,52 +1510,91 @@ static RustTypeDescriptor arrayOf(RustTypeDescriptor type, int len)
15021510

15031511
private static final class RustStruct
15041512
{
1505-
enum Modifier {
1513+
enum Modifier
1514+
{
15061515
PACKED
15071516
}
15081517

15091518
final String name;
15101519
final List<RustStructField> fields;
15111520
final EnumSet<Modifier> modifiers;
15121521

1513-
private RustStruct(String name, List<RustStructField> fields, EnumSet<Modifier> modifiers) {
1522+
private RustStruct(String name, List<RustStructField> fields, EnumSet<Modifier> modifiers)
1523+
{
15141524
this.name = name;
15151525
this.fields = fields;
15161526
this.modifiers = modifiers;
15171527
}
15181528

1519-
public static RustStruct fromTokens(String name, List<NamedToken> tokens, EnumSet<Modifier> modifiers) {
1529+
static RustStruct fromHeader(HeaderStructure header)
1530+
{
1531+
final List<Token> tokens = header.tokens();
1532+
final String originalTypeName = tokens.get(0).applicableTypeName();
1533+
final String formattedTypeName = formatTypeName(originalTypeName);
1534+
final SplitCompositeTokens splitTokens = SplitCompositeTokens.splitInnerTokens(tokens);
1535+
return RustStruct.fromTokens(formattedTypeName,
1536+
splitTokens.nonConstantEncodingTokens(),
1537+
EnumSet.of(RustStruct.Modifier.PACKED));
1538+
}
1539+
1540+
static RustStruct fromTokens(String name, List<NamedToken> tokens, EnumSet<Modifier> modifiers)
1541+
{
15201542
return new RustStruct(name, collectStructFields(tokens), modifiers);
15211543
}
15221544

1523-
void appendDefinitionTo(final Appendable appendable) throws IOException {
1545+
void appendDefinitionTo(final Appendable appendable) throws IOException
1546+
{
15241547
appendStructHeader(appendable, name, modifiers.contains(Modifier.PACKED));
1525-
for (RustStructField field: fields) {
1548+
for (RustStructField field: fields)
1549+
{
15261550
indent(appendable);
15271551
if (field.modifiers.contains(RustStructField.Modifier.PUBLIC)) appendable.append("pub ");
15281552
appendable.append(field.name).append(":").append(field.type.name()).append(",\n");
15291553
}
15301554
appendable.append("}");
15311555
}
1556+
1557+
void appendInstanceTo(final Appendable appendable, int indent, Map<String, String> values) throws IOException
1558+
{
1559+
appendable.append("MessageHeader {\n");
1560+
for (RustStructField field: fields) {
1561+
final String value;
1562+
if (values.containsKey(field.name))
1563+
{
1564+
value = field.type.literalValue(values.get(field.name));
1565+
}
1566+
else
1567+
{
1568+
value = field.type.defaultValue();
1569+
}
1570+
1571+
indent(appendable, indent + 1, "%s: %s,\n", formatMethodName(field.name), value);
1572+
}
1573+
indent(appendable, indent, "}\n");
1574+
}
1575+
15321576
}
15331577

15341578
private static final class RustStructField
15351579
{
1536-
enum Modifier {
1580+
enum Modifier
1581+
{
15371582
PUBLIC
15381583
}
15391584

15401585
final String name;
15411586
final RustTypeDescriptor type;
15421587
final EnumSet<Modifier> modifiers;
15431588

1544-
private RustStructField(String name, RustTypeDescriptor type, EnumSet<Modifier> modifiers) {
1589+
private RustStructField(String name, RustTypeDescriptor type, EnumSet<Modifier> modifiers)
1590+
{
15451591
this.name = name;
15461592
this.type = type;
15471593
this.modifiers = modifiers;
15481594
}
15491595

1550-
private RustStructField(String name, RustTypeDescriptor type) {
1596+
private RustStructField(String name, RustTypeDescriptor type)
1597+
{
15511598
this(name, type, EnumSet.noneOf(Modifier.class));
15521599
}
15531600
}
@@ -1604,6 +1651,8 @@ private void generateMessageHeaderDefault(
16041651
throws IOException
16051652
{
16061653
final HeaderStructure header = ir.headerStructure();
1654+
final RustStruct rustHeader = RustStruct.fromHeader(header);
1655+
16071656
final String messageTypeName = formatTypeName(messageToken.name());
16081657
final String wrapperName = messageTypeName + "MessageHeader";
16091658

@@ -1617,33 +1666,14 @@ private void generateMessageHeaderDefault(
16171666
indent(writer, 1, "fn default() -> %s {\n", wrapperName);
16181667
indent(writer, 2, "%s {\n", wrapperName);
16191668

1620-
indent(writer, 3, "message_header: MessageHeader {\n");
1621-
indent(writer, 4, "%s: %s,\n", formatMethodName("blockLength"),
1622-
generateRustLiteral(header.blockLengthType(), Integer.toString(messageToken.encodedLength())));
1623-
indent(writer, 4, "%s: %s,\n", formatMethodName("templateId"),
1624-
generateRustLiteral(header.templateIdType(), Integer.toString(messageToken.id())));
1625-
indent(writer, 4, "%s: %s,\n", formatMethodName("schemaId"),
1626-
generateRustLiteral(header.schemaIdType(), Integer.toString(ir.id())));
1627-
indent(writer, 4, "%s: %s,\n", formatMethodName("version"),
1628-
generateRustLiteral(header.schemaVersionType(), Integer.toString(ir.version())));
1629-
1630-
// Technically the spec seems to allow non-standard fields in the message header, so we attempt
1631-
// to provide some sort of default for them
1632-
final Set<String> reserved = new HashSet<>(Arrays.asList("blockLength", "templateId", "schemaId",
1633-
"version"));
1634-
1635-
final List<NamedToken> nonReservedNamedTokens = SplitCompositeTokens.splitInnerTokens(header.tokens())
1636-
.nonConstantEncodingTokens()
1637-
.stream()
1638-
.filter((namedToken) -> !reserved.contains(namedToken.name()))
1639-
.collect(Collectors.toList());
1640-
1641-
for (final NamedToken namedToken : nonReservedNamedTokens)
1642-
{
1643-
indent(writer, 4, "%s: Default::default(),\n", formatMethodName(namedToken.name()));
1644-
}
1645-
1646-
indent(writer, 3, "}\n");
1669+
indent(writer, 3, "message_header: ");
1670+
rustHeader.appendInstanceTo(writer, 3,
1671+
new HashMap<String, String>() {{
1672+
put("block_length", Integer.toString(messageToken.encodedLength()));
1673+
put("template_id", Integer.toString(messageToken.id()));
1674+
put("schema_id", Integer.toString(ir.id()));
1675+
put("version", Integer.toString(ir.version()));
1676+
}});
16471677

16481678
indent(writer, 2, "}\n");
16491679
indent(writer, 1, "}\n");

0 commit comments

Comments
 (0)