@@ -305,6 +305,7 @@ impl SourceItemOrderingModuleItemKind {
305305pub struct SourceItemOrderingModuleItemGroupings {
306306 groups : Vec < ( String , Vec < SourceItemOrderingModuleItemKind > ) > ,
307307 lut : HashMap < SourceItemOrderingModuleItemKind , usize > ,
308+ back_lut : HashMap < SourceItemOrderingModuleItemKind , String > ,
308309}
309310
310311impl SourceItemOrderingModuleItemGroupings {
@@ -320,6 +321,30 @@ impl SourceItemOrderingModuleItemGroupings {
320321 lut
321322 }
322323
324+ fn build_back_lut (
325+ groups : & [ ( String , Vec < SourceItemOrderingModuleItemKind > ) ] ,
326+ ) -> HashMap < SourceItemOrderingModuleItemKind , String > {
327+ let mut lut = HashMap :: new ( ) ;
328+ for ( group_name, items) in groups {
329+ for item in items {
330+ lut. insert ( item. clone ( ) , group_name. clone ( ) ) ;
331+ }
332+ }
333+ lut
334+ }
335+
336+ pub fn grouping_name_of ( & self , item : & SourceItemOrderingModuleItemKind ) -> Option < & String > {
337+ self . back_lut . get ( item)
338+ }
339+
340+ pub fn grouping_names ( & self ) -> Vec < String > {
341+ self . groups . iter ( ) . map ( |( name, _) | name. clone ( ) ) . collect ( )
342+ }
343+
344+ pub fn is_grouping ( & self , grouping : & str ) -> bool {
345+ self . groups . iter ( ) . any ( |( g, _) | g == grouping)
346+ }
347+
323348 pub fn module_level_order_of ( & self , item : & SourceItemOrderingModuleItemKind ) -> Option < usize > {
324349 self . lut . get ( item) . copied ( )
325350 }
@@ -330,7 +355,8 @@ impl From<&[(&str, &[SourceItemOrderingModuleItemKind])]> for SourceItemOrdering
330355 let groups: Vec < ( String , Vec < SourceItemOrderingModuleItemKind > ) > =
331356 value. iter ( ) . map ( |item| ( item. 0 . to_string ( ) , item. 1 . to_vec ( ) ) ) . collect ( ) ;
332357 let lut = Self :: build_lut ( & groups) ;
333- Self { groups, lut }
358+ let back_lut = Self :: build_back_lut ( & groups) ;
359+ Self { groups, lut, back_lut }
334360 }
335361}
336362
@@ -348,6 +374,7 @@ impl<'de> Deserialize<'de> for SourceItemOrderingModuleItemGroupings {
348374 let groups = Vec :: < ( String , Vec < SourceItemOrderingModuleItemKind > ) > :: deserialize ( deserializer) ?;
349375 let items_total: usize = groups. iter ( ) . map ( |( _, v) | v. len ( ) ) . sum ( ) ;
350376 let lut = Self :: build_lut ( & groups) ;
377+ let back_lut = Self :: build_back_lut ( & groups) ;
351378
352379 let mut expected_items = SourceItemOrderingModuleItemKind :: all_variants ( ) ;
353380 for item in lut. keys ( ) {
@@ -370,7 +397,7 @@ impl<'de> Deserialize<'de> for SourceItemOrderingModuleItemGroupings {
370397 ) ) ;
371398 }
372399
373- Ok ( Self { groups, lut } )
400+ Ok ( Self { groups, lut, back_lut } )
374401 } else if items_total != all_items. len ( ) {
375402 Err ( de:: Error :: custom ( format ! (
376403 "Some module item kinds were configured more than once, or were missing, in the source ordering configuration. \
@@ -482,6 +509,83 @@ impl Serialize for SourceItemOrderingTraitAssocItemKinds {
482509 }
483510}
484511
512+ /// Describes which specific groupings should have their items ordered
513+ /// alphabetically.
514+ ///
515+ /// This is separate from defining and enforcing groupings. For example,
516+ /// defining enums are grouped before structs still allows for an enum B to be
517+ /// placed before an enum A. Only when enforcing ordering within the grouping,
518+ /// will it be checked if A is placed before B.
519+ #[ derive( Clone , Debug ) ]
520+ pub enum SourceItemOrderingWithinModuleItemGroupings {
521+ /// All groupings should have their items ordered.
522+ All ,
523+
524+ /// None of the groupings should have their order checked.
525+ None ,
526+
527+ /// Only the specified groupings should have their order checked.
528+ Custom ( Vec < String > ) ,
529+ }
530+
531+ impl SourceItemOrderingWithinModuleItemGroupings {
532+ pub fn ordered_within ( & self , grouping_name : & String ) -> bool {
533+ match self {
534+ SourceItemOrderingWithinModuleItemGroupings :: All => true ,
535+ SourceItemOrderingWithinModuleItemGroupings :: None => false ,
536+ SourceItemOrderingWithinModuleItemGroupings :: Custom ( groups) => groups. contains ( grouping_name) ,
537+ }
538+ }
539+ }
540+
541+ /// Helper struct for deserializing the [`SourceItemOrderingWithinModuleItemGroupings`].
542+ #[ derive( Deserialize ) ]
543+ #[ serde( untagged) ]
544+ enum StringOrVecOfString {
545+ String ( String ) ,
546+ Vec ( Vec < String > ) ,
547+ }
548+
549+ impl < ' de > Deserialize < ' de > for SourceItemOrderingWithinModuleItemGroupings {
550+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
551+ where
552+ D : Deserializer < ' de > ,
553+ {
554+ let description = "The available options for configuring an ordering within module item groups are: \
555+ \" all\" , \" none\" , or a list of module item group names \
556+ (as configured with the `module-item-order-groupings` configuration option).";
557+
558+ match StringOrVecOfString :: deserialize ( deserializer) {
559+ Ok ( StringOrVecOfString :: String ( preset) ) if preset == "all" => {
560+ Ok ( SourceItemOrderingWithinModuleItemGroupings :: All )
561+ } ,
562+ Ok ( StringOrVecOfString :: String ( preset) ) if preset == "none" => {
563+ Ok ( SourceItemOrderingWithinModuleItemGroupings :: None )
564+ } ,
565+ Ok ( StringOrVecOfString :: String ( preset) ) => Err ( de:: Error :: custom ( format ! (
566+ "Unknown configuration option: {preset}.\n {description}"
567+ ) ) ) ,
568+ Ok ( StringOrVecOfString :: Vec ( groupings) ) => {
569+ Ok ( SourceItemOrderingWithinModuleItemGroupings :: Custom ( groupings) )
570+ } ,
571+ Err ( e) => Err ( de:: Error :: custom ( format ! ( "{e}\n {description}" ) ) ) ,
572+ }
573+ }
574+ }
575+
576+ impl Serialize for SourceItemOrderingWithinModuleItemGroupings {
577+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
578+ where
579+ S : ser:: Serializer ,
580+ {
581+ match self {
582+ SourceItemOrderingWithinModuleItemGroupings :: All => serializer. serialize_str ( "all" ) ,
583+ SourceItemOrderingWithinModuleItemGroupings :: None => serializer. serialize_str ( "none" ) ,
584+ SourceItemOrderingWithinModuleItemGroupings :: Custom ( vec) => vec. serialize ( serializer) ,
585+ }
586+ }
587+ }
588+
485589// these impls are never actually called but are used by the various config options that default to
486590// empty lists
487591macro_rules! unimplemented_serialize {
0 commit comments