@@ -35,16 +35,18 @@ use crate::provider::CollationMetadataV1;
35
35
use crate :: provider:: CollationReordering ;
36
36
use crate :: provider:: CollationReorderingV1 ;
37
37
use crate :: provider:: CollationRootV1 ;
38
- use crate :: provider:: CollationSpecialPrimaries ;
39
38
use crate :: provider:: CollationSpecialPrimariesV1 ;
39
+ use crate :: provider:: CollationSpecialPrimariesValidated ;
40
40
use crate :: provider:: CollationTailoringV1 ;
41
+ use core:: array;
41
42
use core:: cmp:: Ordering ;
42
43
use core:: convert:: TryFrom ;
43
44
use icu_normalizer:: provider:: DecompositionData ;
44
45
use icu_normalizer:: provider:: DecompositionTables ;
45
46
use icu_normalizer:: provider:: NormalizerNfdDataV1 ;
46
47
use icu_normalizer:: provider:: NormalizerNfdTablesV1 ;
47
48
use icu_normalizer:: Decomposition ;
49
+ use icu_provider:: marker:: ErasedMarker ;
48
50
use icu_provider:: prelude:: * ;
49
51
use smallvec:: SmallVec ;
50
52
use utf16_iter:: Utf16CharsEx ;
@@ -379,7 +381,7 @@ impl LocaleSpecificDataHolder {
379
381
/// Compares strings according to culturally-relevant ordering.
380
382
#[ derive( Debug ) ]
381
383
pub struct Collator {
382
- special_primaries : DataPayload < CollationSpecialPrimariesV1 > ,
384
+ special_primaries : DataPayload < ErasedMarker < CollationSpecialPrimariesValidated < ' static > > > ,
383
385
root : DataPayload < CollationRootV1 > ,
384
386
tailoring : Option < DataPayload < CollationTailoringV1 > > ,
385
387
jamo : DataPayload < CollationJamoV1 > ,
@@ -464,7 +466,7 @@ impl Collator {
464
466
decompositions : DataPayload < NormalizerNfdDataV1 > ,
465
467
tables : DataPayload < NormalizerNfdTablesV1 > ,
466
468
jamo : DataPayload < CollationJamoV1 > ,
467
- mut special_primaries : DataPayload < CollationSpecialPrimariesV1 > ,
469
+ special_primaries : DataPayload < CollationSpecialPrimariesV1 > ,
468
470
prefs : CollatorPreferences ,
469
471
options : CollatorOptions ,
470
472
) -> Result < Self , DataError >
@@ -489,24 +491,35 @@ impl Collator {
489
491
if special_primaries. get ( ) . last_primaries . len ( ) <= ( MaxVariable :: Currency as usize ) {
490
492
return Err ( DataError :: custom ( "invalid" ) . with_marker ( CollationSpecialPrimariesV1 :: INFO ) ) ;
491
493
}
492
- if special_primaries. get ( ) . last_primaries . len ( ) == ( MaxVariable :: Currency as usize ) {
493
- // Data without compressible bits, add hardcoded data
494
- special_primaries = special_primaries. map_project ( |csp, _| CollationSpecialPrimaries {
495
- last_primaries : csp
496
- . last_primaries
497
- . iter ( )
498
- . chain (
499
- CollationSpecialPrimaries :: HARDCODED_FALLBACK
500
- . last_primaries
501
- . iter ( )
502
- . rev ( )
503
- . take ( 4 )
504
- . rev ( ) ,
494
+ let special_primaries = special_primaries. map_project ( |csp, _| {
495
+ if csp. last_primaries . len ( )
496
+ == ( MaxVariable :: Currency as usize )
497
+ + core:: mem:: size_of_val (
498
+ & CollationSpecialPrimariesValidated :: HARDCODED_FALLBACK . compressible_bytes ,
505
499
)
506
- . collect ( ) ,
507
- ..csp
508
- } ) ;
509
- }
500
+ {
501
+ CollationSpecialPrimariesValidated {
502
+ compressible_bytes : array:: from_fn ( |i| {
503
+ #[ allow( clippy:: unwrap_used) ] // protected by the if
504
+ {
505
+ csp. last_primaries
506
+ . get ( ( MaxVariable :: Currency as usize ) + i)
507
+ . unwrap ( )
508
+ }
509
+ } ) ,
510
+ last_primaries : csp. last_primaries . truncated ( MaxVariable :: Currency as usize ) ,
511
+ numeric_primary : csp. numeric_primary ,
512
+ }
513
+ } else {
514
+ // Data without compressible bytes, add hardcoded data
515
+ CollationSpecialPrimariesValidated {
516
+ last_primaries : csp. last_primaries ,
517
+ compressible_bytes : CollationSpecialPrimariesValidated :: HARDCODED_FALLBACK
518
+ . compressible_bytes ,
519
+ numeric_primary : csp. numeric_primary ,
520
+ }
521
+ }
522
+ } ) ;
510
523
511
524
Ok ( Collator {
512
525
special_primaries,
@@ -550,7 +563,7 @@ macro_rules! compare {
550
563
/// borrowed version.
551
564
#[ derive( Debug ) ]
552
565
pub struct CollatorBorrowed < ' a > {
553
- special_primaries : & ' a CollationSpecialPrimaries < ' a > ,
566
+ special_primaries : & ' a CollationSpecialPrimariesValidated < ' a > ,
554
567
root : & ' a CollationData < ' a > ,
555
568
tailoring : Option < & ' a CollationData < ' a > > ,
556
569
jamo : & ' a CollationJamo < ' a > ,
@@ -586,28 +599,26 @@ impl CollatorBorrowed<'static> {
586
599
return Err ( DataError :: custom ( "invalid" ) . with_marker ( CollationJamoV1 :: INFO ) ) ;
587
600
}
588
601
589
- let mut special_primaries =
590
- crate :: provider:: Baked :: SINGLETON_COLLATION_SPECIAL_PRIMARIES_V1 ;
602
+ let special_primaries = crate :: provider:: Baked :: SINGLETON_COLLATION_SPECIAL_PRIMARIES_V1 ;
591
603
// `variant_count` isn't stable yet:
592
604
// https://github.com/rust-lang/rust/issues/73662
593
605
if special_primaries. last_primaries . len ( ) <= ( MaxVariable :: Currency as usize ) {
594
606
return Err ( DataError :: custom ( "invalid" ) . with_marker ( CollationSpecialPrimariesV1 :: INFO ) ) ;
607
+ } else if CollationSpecialPrimariesValidated :: HARDCODED_FALLBACK . numeric_primary
608
+ != special_primaries. numeric_primary
609
+ || CollationSpecialPrimariesValidated :: HARDCODED_FALLBACK
610
+ . last_primaries
611
+ . iter ( )
612
+ . zip ( special_primaries. last_primaries . iter ( ) )
613
+ . any ( |( a, b) | a != b)
614
+ {
615
+ // Baked data without compressible bits, but not matching hardcoded data
616
+ return Err (
617
+ DataError :: custom ( "cannot fall back to hardcoded compressible data" )
618
+ . with_marker ( CollationSpecialPrimariesV1 :: INFO ) ,
619
+ ) ;
595
620
}
596
- if special_primaries. last_primaries . len ( ) == ( MaxVariable :: Currency as usize ) {
597
- // Baked data without compressible bits, use hardcoded data
598
- if CollationSpecialPrimaries :: HARDCODED_FALLBACK . numeric_primary
599
- != special_primaries. numeric_primary
600
- || CollationSpecialPrimaries :: HARDCODED_FALLBACK
601
- . last_primaries
602
- . iter ( )
603
- . zip ( special_primaries. last_primaries . iter ( ) )
604
- . any ( |( a, b) | a != b)
605
- {
606
- return Err ( DataError :: custom ( "cannot fall back to compressible data" )
607
- . with_marker ( CollationSpecialPrimariesV1 :: INFO ) ) ;
608
- }
609
- special_primaries = CollationSpecialPrimaries :: HARDCODED_FALLBACK ;
610
- }
621
+ let special_primaries = CollationSpecialPrimariesValidated :: HARDCODED_FALLBACK ;
611
622
612
623
// Attribute belongs closer to `unwrap`, but
613
624
// https://github.com/rust-lang/rust/issues/15701
0 commit comments