@@ -1024,16 +1024,61 @@ impl EncodeIntoContext for SearchKey<'_> {
10241024}
10251025
10261026impl EncodeIntoContext for SequenceSet {
1027+ #[ cfg( not( feature = "quirk_dedup_sort_seq_encoding" ) ) ]
10271028 fn encode_ctx ( & self , ctx : & mut EncodeContext ) -> std:: io:: Result < ( ) > {
10281029 join_serializable ( self . 0 . as_ref ( ) , b"," , ctx)
10291030 }
1031+
1032+ #[ cfg( feature = "quirk_dedup_sort_seq_encoding" ) ]
1033+ fn encode_ctx ( & self , ctx : & mut EncodeContext ) -> std:: io:: Result < ( ) > {
1034+ let mut seq_set = self . 0 . as_ref ( ) . to_vec ( ) ;
1035+
1036+ if seq_set. len ( ) == 1 {
1037+ return seq_set. remove ( 0 ) . encode_ctx ( ctx) ;
1038+ }
1039+
1040+ seq_set. sort_by ( |a, b| a. partial_cmp ( b) . unwrap_or ( std:: cmp:: Ordering :: Equal ) ) ;
1041+
1042+ let mut a = 0 ;
1043+ let mut b = 1 ;
1044+
1045+ while b < seq_set. len ( ) {
1046+ if seq_set[ a] . partial_cmp ( & seq_set[ b] ) . is_some ( ) {
1047+ a += 1 ;
1048+ b += 1 ;
1049+ continue ;
1050+ }
1051+
1052+ match ( & seq_set[ a] , & seq_set[ b] ) {
1053+ ( Sequence :: Single ( _) , _) => {
1054+ seq_set. remove ( a) ;
1055+ }
1056+ ( Sequence :: Range ( _, _) , Sequence :: Single ( _) ) => {
1057+ seq_set. remove ( b) ;
1058+ }
1059+ ( Sequence :: Range ( a1, a2) , Sequence :: Range ( b1, b2) ) => {
1060+ let min = a1. clone ( ) . min ( a2. clone ( ) ) . min ( b1. clone ( ) ) . min ( b2. clone ( ) ) ;
1061+ let max = a1. clone ( ) . max ( a2. clone ( ) ) . max ( b1. clone ( ) ) . max ( b2. clone ( ) ) ;
1062+ let _ = std:: mem:: replace ( & mut seq_set[ a] , Sequence :: Range ( min, max) ) ;
1063+ seq_set. remove ( b) ;
1064+ }
1065+ }
1066+ }
1067+
1068+ join_serializable ( & seq_set, b"," , ctx)
1069+ }
10301070}
10311071
10321072impl EncodeIntoContext for Sequence {
10331073 fn encode_ctx ( & self , ctx : & mut EncodeContext ) -> std:: io:: Result < ( ) > {
10341074 match self {
10351075 Sequence :: Single ( seq_no) => seq_no. encode_ctx ( ctx) ,
10361076 Sequence :: Range ( from, to) => {
1077+ #[ cfg( feature = "quirk_dedup_sort_seq_encoding" ) ]
1078+ let from = from. min ( to) ;
1079+ #[ cfg( feature = "quirk_dedup_sort_seq_encoding" ) ]
1080+ let to = from. max ( to) ;
1081+
10371082 from. encode_ctx ( ctx) ?;
10381083 ctx. write_all ( b":" ) ?;
10391084 to. encode_ctx ( ctx)
@@ -2128,6 +2173,32 @@ mod tests {
21282173
21292174 use super :: * ;
21302175
2176+ #[ cfg( feature = "quirk_dedup_sort_seq_encoding" ) ]
2177+ #[ test]
2178+ fn test_sequence_reordering ( ) {
2179+ let tests = [
2180+ ( "1,2,3,4" , "1,2,3,4" ) ,
2181+ ( "3,1,2,4" , "1,2,3,4" ) ,
2182+ ( "3:1,5" , "1:3,5" ) ,
2183+ ( "5,3:1" , "1:3,5" ) ,
2184+ ( "3,3:1" , "1:3" ) ,
2185+ ( "3:1,1" , "1:3" ) ,
2186+ ( "3:1,2:5" , "1:5" ) ,
2187+ ( "3:1,4:9" , "1:3,4:9" ) ,
2188+ ( "9:4,3:1" , "1:3,4:9" ) ,
2189+ ( "8:10,3:1,2:5,9" , "1:5,8:10" ) ,
2190+ ] ;
2191+
2192+ for ( expected, got) in tests {
2193+ let mut ctx = EncodeContext :: default ( ) ;
2194+ SequenceSet :: try_from ( expected)
2195+ . unwrap ( )
2196+ . encode_ctx ( & mut ctx)
2197+ . unwrap ( ) ;
2198+ assert_eq ! ( got, escape_byte_string( & ctx. accumulator) ) ;
2199+ }
2200+ }
2201+
21312202 #[ test]
21322203 fn test_api_encoder_usage ( ) {
21332204 let cmd = Command :: new (
0 commit comments