@@ -19,6 +19,7 @@ pub use fluent_bundle::types::FluentType;
1919use fluent_bundle:: FluentResource ;
2020pub use fluent_bundle:: { self , FluentArgs , FluentError , FluentValue } ;
2121use fluent_syntax:: parser:: ParserError ;
22+ use icu_list:: ListFormatter ;
2223use icu_provider_adapters:: fallback:: { LocaleFallbackProvider , LocaleFallbacker } ;
2324#[ cfg( parallel_compiler) ]
2425use intl_memoizer:: concurrent:: IntlLangMemoizer ;
@@ -528,85 +529,104 @@ fn icu_locale_from_unic_langid(lang: LanguageIdentifier) -> Option<icu_locid::Lo
528529 icu_locid:: Locale :: try_from_bytes ( lang. to_string ( ) . as_bytes ( ) ) . ok ( )
529530}
530531
531- pub fn fluent_value_from_str_list_sep_by_and ( l : Vec < Cow < ' _ , str > > ) -> FluentValue < ' _ > {
532- // Fluent requires 'static value here for its AnyEq usages.
533- # [ derive ( Clone , PartialEq , Debug ) ]
534- struct FluentStrListSepByAnd ( Vec < String > ) ;
532+ # [ derive ( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
533+ enum Separator {
534+ And ,
535+ }
535536
536- impl FluentType for FluentStrListSepByAnd {
537- fn duplicate ( & self ) -> Box < dyn FluentType + Send > {
538- Box :: new ( self . clone ( ) )
537+ impl Separator {
538+ fn list_formatter (
539+ & self ,
540+ data_provider : & LocaleFallbackProvider < rustc_baked_icu_data:: BakedDataProvider > ,
541+ locale : icu_locid:: Locale ,
542+ ) -> ListFormatter {
543+ match self {
544+ Separator :: And => icu_list:: ListFormatter :: try_new_and_with_length_with_any_provider (
545+ & data_provider,
546+ & locale. into ( ) ,
547+ icu_list:: ListLength :: Wide ,
548+ ) ,
539549 }
550+ . expect ( "Failed to create list formatter" )
551+ }
552+ }
540553
541- fn as_string ( & self , intls : & intl_memoizer:: IntlLangMemoizer ) -> Cow < ' static , str > {
542- let result = intls
543- . with_try_get :: < MemoizableListFormatter , _ , _ > ( ( ) , |list_formatter| {
544- list_formatter. format_to_string ( self . 0 . iter ( ) )
545- } )
546- . unwrap ( ) ;
547- Cow :: Owned ( result)
548- }
554+ #[ derive( Clone , PartialEq , Debug ) ]
555+ struct FluentStrListSepBy {
556+ sep : Separator ,
557+ items : Vec < String > ,
558+ }
549559
550- #[ cfg( not( parallel_compiler) ) ]
551- fn as_string_threadsafe (
552- & self ,
553- _intls : & intl_memoizer:: concurrent:: IntlLangMemoizer ,
554- ) -> Cow < ' static , str > {
555- unreachable ! ( "`as_string_threadsafe` is not used in non-parallel rustc" )
556- }
560+ impl FluentType for FluentStrListSepBy {
561+ fn duplicate ( & self ) -> Box < dyn FluentType + Send > {
562+ Box :: new ( self . clone ( ) )
563+ }
557564
558- #[ cfg( parallel_compiler) ]
559- fn as_string_threadsafe (
560- & self ,
561- intls : & intl_memoizer:: concurrent:: IntlLangMemoizer ,
562- ) -> Cow < ' static , str > {
563- let result = intls
564- . with_try_get :: < MemoizableListFormatter , _ , _ > ( ( ) , |list_formatter| {
565- list_formatter. format_to_string ( self . 0 . iter ( ) )
566- } )
567- . unwrap ( ) ;
568- Cow :: Owned ( result)
569- }
565+ fn as_string ( & self , intls : & intl_memoizer:: IntlLangMemoizer ) -> Cow < ' static , str > {
566+ let result = intls
567+ . with_try_get :: < MemoizableListFormatter , _ , _ > ( self . sep , |list_formatter| {
568+ list_formatter. format_to_string ( self . items . iter ( ) )
569+ } )
570+ . unwrap ( ) ;
571+ Cow :: Owned ( result)
572+ }
573+
574+ #[ cfg( not( parallel_compiler) ) ]
575+ fn as_string_threadsafe (
576+ & self ,
577+ _intls : & intl_memoizer:: concurrent:: IntlLangMemoizer ,
578+ ) -> Cow < ' static , str > {
579+ unreachable ! ( "`as_string_threadsafe` is not used in non-parallel rustc" )
580+ }
581+
582+ #[ cfg( parallel_compiler) ]
583+ fn as_string_threadsafe (
584+ & self ,
585+ intls : & intl_memoizer:: concurrent:: IntlLangMemoizer ,
586+ ) -> Cow < ' static , str > {
587+ let result = intls
588+ . with_try_get :: < MemoizableListFormatter , _ , _ > ( self . sep , |list_formatter| {
589+ list_formatter. format_to_string ( self . items . iter ( ) )
590+ } )
591+ . unwrap ( ) ;
592+ Cow :: Owned ( result)
570593 }
594+ }
571595
572- struct MemoizableListFormatter ( icu_list:: ListFormatter ) ;
596+ struct MemoizableListFormatter ( icu_list:: ListFormatter ) ;
573597
574- impl std:: ops:: Deref for MemoizableListFormatter {
575- type Target = icu_list:: ListFormatter ;
576- fn deref ( & self ) -> & Self :: Target {
577- & self . 0
578- }
598+ impl std:: ops:: Deref for MemoizableListFormatter {
599+ type Target = icu_list:: ListFormatter ;
600+ fn deref ( & self ) -> & Self :: Target {
601+ & self . 0
579602 }
603+ }
580604
581- impl intl_memoizer:: Memoizable for MemoizableListFormatter {
582- type Args = ( ) ;
583- type Error = ( ) ;
584-
585- fn construct ( lang : LanguageIdentifier , _args : Self :: Args ) -> Result < Self , Self :: Error >
586- where
587- Self : Sized ,
588- {
589- let baked_data_provider = rustc_baked_icu_data:: baked_data_provider ( ) ;
590- let locale_fallbacker =
591- LocaleFallbacker :: try_new_with_any_provider ( & baked_data_provider)
592- . expect ( "Failed to create fallback provider" ) ;
593- let data_provider =
594- LocaleFallbackProvider :: new_with_fallbacker ( baked_data_provider, locale_fallbacker) ;
595- let locale = icu_locale_from_unic_langid ( lang)
596- . unwrap_or_else ( || rustc_baked_icu_data:: supported_locales:: EN ) ;
597- let list_formatter =
598- icu_list:: ListFormatter :: try_new_and_with_length_with_any_provider (
599- & data_provider,
600- & locale. into ( ) ,
601- icu_list:: ListLength :: Wide ,
602- )
603- . expect ( "Failed to create list formatter" ) ;
604-
605- Ok ( MemoizableListFormatter ( list_formatter) )
606- }
605+ impl intl_memoizer:: Memoizable for MemoizableListFormatter {
606+ type Args = Separator ;
607+ type Error = ( ) ;
608+
609+ fn construct ( lang : LanguageIdentifier , separator : Separator ) -> Result < Self , Self :: Error >
610+ where
611+ Self : Sized ,
612+ {
613+ let baked_data_provider = rustc_baked_icu_data:: baked_data_provider ( ) ;
614+ let locale_fallbacker = LocaleFallbacker :: try_new_with_any_provider ( & baked_data_provider)
615+ . expect ( "Failed to create fallback provider" ) ;
616+ let data_provider =
617+ LocaleFallbackProvider :: new_with_fallbacker ( baked_data_provider, locale_fallbacker) ;
618+ let locale = icu_locale_from_unic_langid ( lang)
619+ . unwrap_or_else ( || rustc_baked_icu_data:: supported_locales:: EN ) ;
620+
621+ let list_formatter = separator. list_formatter ( & data_provider, locale) ;
622+
623+ Ok ( MemoizableListFormatter ( list_formatter) )
607624 }
625+ }
608626
609- let l = l. into_iter ( ) . map ( |x| x. into_owned ( ) ) . collect ( ) ;
627+ pub fn fluent_value_from_str_list_sep_by_and ( l : Vec < Cow < ' _ , str > > ) -> FluentValue < ' _ > {
628+ // Fluent requires 'static value here for its AnyEq usages.
629+ let items = l. into_iter ( ) . map ( |x| x. into_owned ( ) ) . collect ( ) ;
610630
611- FluentValue :: Custom ( Box :: new ( FluentStrListSepByAnd ( l ) ) )
631+ FluentValue :: Custom ( Box :: new ( FluentStrListSepBy { sep : Separator :: And , items } ) )
612632}
0 commit comments