Skip to content

Commit 7267483

Browse files
committed
Factor out ICU4X list formatter creation
1 parent 8e328bb commit 7267483

File tree

1 file changed

+88
-68
lines changed
  • compiler/rustc_error_messages/src

1 file changed

+88
-68
lines changed

compiler/rustc_error_messages/src/lib.rs

Lines changed: 88 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub use fluent_bundle::types::FluentType;
1919
use fluent_bundle::FluentResource;
2020
pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue};
2121
use fluent_syntax::parser::ParserError;
22+
use icu_list::ListFormatter;
2223
use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker};
2324
#[cfg(parallel_compiler)]
2425
use 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

Comments
 (0)