@@ -106,9 +106,10 @@ private void generateGroupFieldRepresentations(
106106 {
107107 for (final GroupTreeNode node : groupTree )
108108 {
109- appendStructHeader (appendable , node .contextualName + "Member" , true );
110- appendStructFields (appendable , node .simpleNamedFields );
111- appendable .append ("}\n " );
109+ final RustStruct struct = RustStruct .fromTokens (node .contextualName + "Member" ,
110+ node .simpleNamedFields ,
111+ EnumSet .of (RustStruct .Modifier .PACKED ));
112+ struct .appendDefinitionTo (appendable );
112113
113114 generateConstantAccessorImpl (appendable , node .contextualName + "Member" , node .rawFields );
114115
@@ -138,9 +139,10 @@ private static Optional<FieldsRepresentationSummary> generateFieldsRepresentatio
138139 final String representationStruct = messageTypeName + "Fields" ;
139140 try (Writer writer = outputManager .createOutput (messageTypeName + " Fixed-size Fields" ))
140141 {
141- appendStructHeader (writer , representationStruct , true );
142- appendStructFields (writer , namedFieldTokens );
143- writer .append ("}\n " );
142+ final RustStruct struct = RustStruct .fromTokens (representationStruct , namedFieldTokens ,
143+ EnumSet .of (RustStruct .Modifier .PACKED ));
144+ struct .appendDefinitionTo (writer );
145+ writer .append ("\n " );
144146
145147 generateConstantAccessorImpl (writer , representationStruct , components .fields );
146148 }
@@ -1391,29 +1393,166 @@ private static void generateSingleComposite(final List<Token> tokens, final Outp
13911393
13921394 try (Writer writer = outputManager .createOutput (formattedTypeName ))
13931395 {
1394- appendStructHeader (writer , formattedTypeName , true );
1395- appendStructFields (writer , splitTokens .nonConstantEncodingTokens ());
1396- writer .append ("}\n " );
1396+ final RustStruct struct = RustStruct .fromTokens (formattedTypeName ,
1397+ splitTokens .nonConstantEncodingTokens (),
1398+ EnumSet .of (RustStruct .Modifier .PACKED ));
1399+ struct .appendDefinitionTo (writer );
13971400
13981401 generateConstantAccessorImpl (writer , formattedTypeName , getMessageBody (tokens ));
13991402 }
14001403 }
14011404
1405+ private interface RustTypeDescriptor
1406+ {
1407+ String name ();
1408+ String literal (String valueRep );
1409+ }
1410+
1411+ private static final class RustArrayType implements RustTypeDescriptor
1412+ {
1413+ private final RustTypeDescriptor componentType ;
1414+ private final int length ;
1415+
1416+ private RustArrayType (RustTypeDescriptor component , int length ) {
1417+ this .componentType = component ;
1418+ this .length = length ;
1419+ }
1420+
1421+ @ Override
1422+ public String name ()
1423+ {
1424+ return getRustStaticArrayString (componentType .name (), length );
1425+ }
1426+
1427+ @ Override
1428+ public String literal (String valueRep )
1429+ {
1430+ return getRustStaticArrayString (valueRep + componentType .name (), length );
1431+ }
1432+ }
1433+
1434+ private static final class RustPrimitiveType implements RustTypeDescriptor
1435+ {
1436+ private final String name ;
1437+
1438+ private RustPrimitiveType (String name ) {
1439+ this .name = name ;
1440+ }
1441+
1442+ @ Override
1443+ public String name ()
1444+ {
1445+ return name ;
1446+ }
1447+
1448+ @ Override
1449+ public String literal (String valueRep )
1450+ {
1451+ return valueRep + name ;
1452+ }
1453+ }
1454+
1455+ private static final class AnyRustType implements RustTypeDescriptor
1456+ {
1457+ private final String name ;
1458+
1459+ private AnyRustType (String name ) {
1460+ this .name = name ;
1461+ }
1462+
1463+ @ Override
1464+ public String name ()
1465+ {
1466+ return name ;
1467+ }
1468+
1469+ @ Override
1470+ public String literal (String valueRep )
1471+ {
1472+ final String msg = String .format ("Cannot produce a literal value %s of type %s!" , valueRep , name );
1473+ throw new UnsupportedOperationException (msg );
1474+ }
1475+ }
1476+
1477+ private static final class RustTypes
1478+ {
1479+ static final RustTypeDescriptor u8 = new RustPrimitiveType ("u8" );
1480+
1481+ static RustTypeDescriptor ofPrimitiveToken (Token token )
1482+ {
1483+ final PrimitiveType primitiveType = token .encoding ().primitiveType ();
1484+ final String rustPrimitiveType = RustUtil .rustTypeName (primitiveType );
1485+ final RustPrimitiveType type = new RustPrimitiveType (rustPrimitiveType );
1486+ if (token .arrayLength () > 1 ) {
1487+ return new RustArrayType (type , token .arrayLength ());
1488+ }
1489+ return type ;
1490+ }
1491+
1492+ static RustTypeDescriptor ofGeneratedToken (Token token )
1493+ {
1494+ return new AnyRustType (formatTypeName (token .applicableTypeName ()));
1495+ }
1496+
1497+ static RustTypeDescriptor arrayOf (RustTypeDescriptor type , int len )
1498+ {
1499+ return new RustArrayType (type , len );
1500+ }
1501+ }
1502+
1503+ private static final class RustStruct
1504+ {
1505+ enum Modifier {
1506+ PACKED
1507+ }
1508+
1509+ final String name ;
1510+ final List <RustStructField > fields ;
1511+ final EnumSet <Modifier > modifiers ;
1512+
1513+ private RustStruct (String name , List <RustStructField > fields , EnumSet <Modifier > modifiers ) {
1514+ this .name = name ;
1515+ this .fields = fields ;
1516+ this .modifiers = modifiers ;
1517+ }
1518+
1519+ public static RustStruct fromTokens (String name , List <NamedToken > tokens , EnumSet <Modifier > modifiers ) {
1520+ return new RustStruct (name , collectStructFields (tokens ), modifiers );
1521+ }
1522+
1523+ void appendDefinitionTo (final Appendable appendable ) throws IOException {
1524+ appendStructHeader (appendable , name , modifiers .contains (Modifier .PACKED ));
1525+ for (RustStructField field : fields ) {
1526+ indent (appendable );
1527+ if (field .modifiers .contains (RustStructField .Modifier .PUBLIC )) appendable .append ("pub " );
1528+ appendable .append (field .name ).append (":" ).append (field .type .name ()).append (",\n " );
1529+ }
1530+ appendable .append ("}" );
1531+ }
1532+ }
1533+
14021534 private static final class RustStructField
14031535 {
1404- final boolean isPub ;
1536+ enum Modifier {
1537+ PUBLIC
1538+ }
1539+
14051540 final String name ;
1406- final String value ;
1541+ final RustTypeDescriptor type ;
1542+ final EnumSet <Modifier > modifiers ;
14071543
1408- private RustStructField (boolean isPub , String name , String value ) {
1409- this .isPub = isPub ;
1544+ private RustStructField (String name , RustTypeDescriptor type , EnumSet <Modifier > modifiers ) {
14101545 this .name = name ;
1411- this .value = value ;
1546+ this .type = type ;
1547+ this .modifiers = modifiers ;
1548+ }
1549+
1550+ private RustStructField (String name , RustTypeDescriptor type ) {
1551+ this (name , type , EnumSet .noneOf (Modifier .class ));
14121552 }
14131553 }
14141554
1415- private static void appendStructFields (final Appendable appendable , final List <NamedToken > namedTokens )
1416- throws IOException
1555+ private static List <RustStructField > collectStructFields (final List <NamedToken > namedTokens )
14171556 {
14181557 final List <RustStructField > fields = new ArrayList <>();
14191558 int totalSize = 0 ;
@@ -1430,37 +1569,32 @@ private static void appendStructFields(final Appendable appendable, final List<N
14301569 // need padding when field offsets imply gaps
14311570 final int offset = typeToken .offset ();
14321571 if (offset != totalSize ) {
1433- final String value = getRustStaticArrayString ( "u8" , offset - totalSize );
1434- fields .add (new RustStructField (false , propertyName + "_padding" , value ));
1572+ final RustTypeDescriptor type = RustTypes . arrayOf ( RustTypes . u8 , offset - totalSize );
1573+ fields .add (new RustStructField (propertyName + "_padding" , type ));
14351574 }
1436- totalSize += typeToken .encodedLength ();
1575+ totalSize = offset + typeToken .encodedLength ();
14371576
1577+ final RustTypeDescriptor type ;
14381578 switch (typeToken .signal ())
14391579 {
14401580 case ENCODING :
1441- final String rustPrimitiveType = RustUtil .rustTypeName (typeToken .encoding ().primitiveType ());
1442- final String rustFieldType = getRustTypeForPrimitivePossiblyArray (typeToken , rustPrimitiveType );
1443- fields .add (new RustStructField (true , propertyName , rustFieldType ));
1581+ type = RustTypes .ofPrimitiveToken (typeToken );
1582+ fields .add (new RustStructField (propertyName , type , EnumSet .of (RustStructField .Modifier .PUBLIC )));
14441583 break ;
14451584
14461585 case BEGIN_ENUM :
14471586 case BEGIN_SET :
14481587 case BEGIN_COMPOSITE :
1449- fields .add (new RustStructField (true , propertyName , formatTypeName (typeToken .applicableTypeName ())));
1588+ type = RustTypes .ofGeneratedToken (typeToken );
1589+ fields .add (new RustStructField (propertyName , type , EnumSet .of (RustStructField .Modifier .PUBLIC )));
14501590 break ;
14511591
14521592 default :
14531593 throw new IllegalStateException (
14541594 format ("Unsupported struct property from %s" , typeToken .toString ()));
14551595 }
1456-
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 ();
14631596 }
1597+ return fields ;
14641598 }
14651599
14661600 private void generateMessageHeaderDefault (
0 commit comments