@@ -519,13 +519,19 @@ impl<'a> FmtVisitor<'a> {
519519 self . push_rewrite ( static_parts. span , rewrite) ;
520520 }
521521
522- pub ( crate ) fn visit_struct ( & mut self , struct_parts : & StructParts < ' _ > ) {
522+ pub ( crate ) fn visit_struct ( & mut self , struct_parts : & StructParts < ' _ > , sort : bool ) {
523523 let is_tuple = match struct_parts. def {
524524 ast:: VariantData :: Tuple ( ..) => true ,
525525 _ => false ,
526526 } ;
527- let rewrite = format_struct ( & self . get_context ( ) , struct_parts, self . block_indent , None )
528- . map ( |s| if is_tuple { s + ";" } else { s } ) ;
527+ let rewrite = format_struct (
528+ & self . get_context ( ) ,
529+ struct_parts,
530+ self . block_indent ,
531+ None ,
532+ sort,
533+ )
534+ . map ( |s| if is_tuple { s + ";" } else { s } ) ;
529535 self . push_rewrite ( struct_parts. span , rewrite) ;
530536 }
531537
@@ -705,6 +711,7 @@ impl<'a> FmtVisitor<'a> {
705711 & StructParts :: from_variant ( field, & context) ,
706712 self . block_indent ,
707713 Some ( one_line_width) ,
714+ false ,
708715 ) ?,
709716 ast:: VariantData :: Unit ( ..) => rewrite_ident ( & context, field. ident ) . to_owned ( ) ,
710717 } ;
@@ -1153,14 +1160,15 @@ fn format_struct(
11531160 struct_parts : & StructParts < ' _ > ,
11541161 offset : Indent ,
11551162 one_line_width : Option < usize > ,
1163+ sort : bool ,
11561164) -> Option < String > {
11571165 match struct_parts. def {
11581166 ast:: VariantData :: Unit ( ..) => format_unit_struct ( context, struct_parts, offset) ,
11591167 ast:: VariantData :: Tuple ( fields, _) => {
11601168 format_tuple_struct ( context, struct_parts, fields, offset)
11611169 }
11621170 ast:: VariantData :: Struct { fields, .. } => {
1163- format_struct_struct ( context, struct_parts, fields, offset, one_line_width)
1171+ format_struct_struct ( context, struct_parts, fields, offset, one_line_width, sort )
11641172 }
11651173 }
11661174}
@@ -1439,6 +1447,7 @@ pub(crate) fn format_struct_struct(
14391447 fields : & [ ast:: FieldDef ] ,
14401448 offset : Indent ,
14411449 one_line_width : Option < usize > ,
1450+ sort : bool ,
14421451) -> Option < String > {
14431452 let mut result = String :: with_capacity ( 1024 ) ;
14441453 let span = struct_parts. span ;
@@ -1507,12 +1516,36 @@ pub(crate) fn format_struct_struct(
15071516 let one_line_budget =
15081517 one_line_width. map_or ( 0 , |one_line_width| min ( one_line_width, one_line_budget) ) ;
15091518
1519+ let ranks: Option < Vec < _ > > = if sort {
1520+ // get the sequence of indices that would sort the vec
1521+ let indices: Vec < usize > = fields
1522+ . iter ( )
1523+ . enumerate ( )
1524+ . sorted_by ( |( _, field_a) , ( _, field_b) | {
1525+ field_a
1526+ . ident
1527+ . zip ( field_b. ident )
1528+ . map ( |( a, b) | a. name . as_str ( ) . cmp ( b. name . as_str ( ) ) )
1529+ . unwrap_or ( Ordering :: Equal )
1530+ } )
1531+ . map ( |( i, _) | i)
1532+ . collect ( ) ;
1533+ // create a vec with ranks for the fields, allowing for use in Itertools.sorted_by_key
1534+ let mut ranks = vec ! [ 0 ; indices. len( ) ] ;
1535+ for ( rank, original_index) in indices. into_iter ( ) . enumerate ( ) {
1536+ ranks[ original_index] = rank;
1537+ }
1538+ Some ( ranks)
1539+ } else {
1540+ None
1541+ } ;
15101542 let items_str = rewrite_with_alignment (
15111543 fields,
15121544 context,
15131545 Shape :: indented ( offset. block_indent ( context. config ) , context. config ) . sub_width ( 1 ) ?,
15141546 mk_sp ( body_lo, span. hi ( ) ) ,
15151547 one_line_budget,
1548+ ranks. as_ref ( ) . map ( |v| v. as_slice ( ) ) ,
15161549 ) ?;
15171550
15181551 if !items_str. contains ( '\n' )
0 commit comments