-
-
Notifications
You must be signed in to change notification settings - Fork 484
Restructure Intl implementation to use ICU4X's locale preferences #4589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
4e685b5
49cc51f
d561407
26b3c39
23bdf34
796ca0b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,24 @@ | ||
| use std::str::FromStr; | ||
|
|
||
| use icu_collator::{ | ||
| CollatorPreferences, | ||
| options::{CaseLevel, Strength}, | ||
| preferences::CollationCaseFirst, | ||
| preferences::{CollationCaseFirst, CollationType}, | ||
| provider::CollationMetadataV1, | ||
| }; | ||
| use icu_locale::{LanguageIdentifier, preferences::PreferenceKey}; | ||
| use icu_provider::{ | ||
| DataMarkerAttributes, | ||
| prelude::icu_locale_core::{extensions::unicode, preferences::LocalePreferences}, | ||
| }; | ||
|
|
||
| use crate::{ | ||
| Context, JsNativeError, JsResult, JsValue, | ||
| builtins::options::{OptionType, ParsableOptionType}, | ||
| builtins::{ | ||
| intl::{ServicePreferences, locale::validate_extension}, | ||
| options::{OptionType, ParsableOptionType}, | ||
| }, | ||
| context::icu::IntlProvider, | ||
| }; | ||
|
|
||
| #[derive(Debug, Clone, Copy)] | ||
|
|
@@ -97,3 +108,60 @@ impl OptionType for CollationCaseFirst { | |
| } | ||
| } | ||
| } | ||
|
|
||
| impl ServicePreferences for CollatorPreferences { | ||
| fn validate(&mut self, id: &LanguageIdentifier, provider: &IntlProvider) { | ||
| self.collation_type = self.collation_type.take().filter(|co| { | ||
| let attr = DataMarkerAttributes::from_str_or_panic(co.as_str()); | ||
| co != &CollationType::Search | ||
| && validate_extension::<CollationMetadataV1>(id, attr, provider) | ||
| }); | ||
| } | ||
|
|
||
| fn as_unicode(&self) -> unicode::Unicode { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think in some cases we have impl From Preferences for Locale
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also thought that, but after looking at the preferences code, it seems like it was commented out: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably there just wasnt a need for it yet. |
||
| let mut exts = unicode::Unicode::new(); | ||
|
|
||
| if let Some(co) = self.collation_type | ||
| && let Some(value) = co.unicode_extension_value() | ||
| { | ||
| exts.keywords.set(unicode::key!("co"), value); | ||
| } | ||
|
|
||
| if let Some(kn) = self.numeric_ordering | ||
| && let Some(value) = kn.unicode_extension_value() | ||
| { | ||
| exts.keywords.set(unicode::key!("kn"), value); | ||
| } | ||
|
|
||
| if let Some(kf) = self.case_first | ||
| && let Some(value) = kf.unicode_extension_value() | ||
| { | ||
| exts.keywords.set(unicode::key!("kf"), value); | ||
| } | ||
|
|
||
| exts | ||
| } | ||
|
|
||
| fn extended(&self, other: &Self) -> Self { | ||
| let mut result = *self; | ||
| result.extend(*other); | ||
| result | ||
| } | ||
|
|
||
| fn intersection(&self, other: &Self) -> Self { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preferences have a merge operation already
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This the opposite though; it takes two preference objects and gets the preferences that are the same in both. We need this because ECMA402 requires correctly setting up the locale with the extensions that were "used" by the locale resolution algorithm. Here I implemented that by first extending the locale prefs with the option prefs, then taking the intersection of the full prefs with the locale prefs to see which ones were not changed. |
||
| let mut inter = *self; | ||
| if inter.locale_preferences != other.locale_preferences { | ||
| inter.locale_preferences = LocalePreferences::default(); | ||
| } | ||
| if inter.collation_type != other.collation_type { | ||
| inter.collation_type.take(); | ||
| } | ||
| if inter.case_first != other.case_first { | ||
| inter.case_first.take(); | ||
| } | ||
| if inter.numeric_ordering != other.numeric_ordering { | ||
| inter.numeric_ordering.take(); | ||
| } | ||
| inter | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good, this is Ecma specific functionality so it should be here in boa
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, extension validation like this seems to be a good candidate for a future "icu4x-ecma402" glue crate