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