@@ -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