Skip to content
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

Cleanup get_option and calls to the function #3355

Merged
merged 1 commit into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 17 additions & 22 deletions boa_engine/src/builtins/intl/collator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::{

use super::{
locale::{canonicalize_locale_list, resolve_locale, supported_locales, validate_extension},
options::{coerce_options_to_object, IntlOptions, LocaleMatcher},
options::{coerce_options_to_object, IntlOptions},
Service,
};

Expand Down Expand Up @@ -241,31 +241,28 @@ impl BuiltInConstructor for Collator {
// a. Let localeData be %Collator%.[[SortLocaleData]].
// 6. Else,
// a. Let localeData be %Collator%.[[SearchLocaleData]].
let usage =
get_option::<Usage>(&options, utf16!("usage"), false, context)?.unwrap_or_default();
let usage = get_option(&options, utf16!("usage"), context)?.unwrap_or_default();

// 7. Let opt be a new Record.
// 8. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
// 9. Set opt.[[localeMatcher]] to matcher.
let matcher =
get_option::<LocaleMatcher>(&options, utf16!("localeMatcher"), false, context)?
.unwrap_or_default();
let matcher = get_option(&options, utf16!("localeMatcher"), context)?.unwrap_or_default();

// 10. Let collation be ? GetOption(options, "collation", string, empty, undefined).
// 11. If collation is not undefined, then
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
// 12. Set opt.[[co]] to collation.
let collation = get_option::<Value>(&options, utf16!("collation"), false, context)?;
let collation = get_option(&options, utf16!("collation"), context)?;

// 13. Let numeric be ? GetOption(options, "numeric", boolean, empty, undefined).
// 14. If numeric is not undefined, then
// a. Let numeric be ! ToString(numeric).
// 15. Set opt.[[kn]] to numeric.
let numeric = get_option::<bool>(&options, utf16!("numeric"), false, context)?;
let numeric = get_option(&options, utf16!("numeric"), context)?;

// 16. Let caseFirst be ? GetOption(options, "caseFirst", string, « "upper", "lower", "false" », undefined).
// 17. Set opt.[[kf]] to caseFirst.
let case_first = get_option::<CaseFirst>(&options, utf16!("caseFirst"), false, context)?;
let case_first = get_option(&options, utf16!("caseFirst"), context)?;

let mut intl_options = IntlOptions {
matcher,
Expand Down Expand Up @@ -314,22 +311,20 @@ impl BuiltInConstructor for Collator {

// 26. Let sensitivity be ? GetOption(options, "sensitivity", string, « "base", "accent", "case", "variant" », undefined).
// 28. Set collator.[[Sensitivity]] to sensitivity.
let sensitivity =
get_option::<Sensitivity>(&options, utf16!("sensitivity"), false, context)?
// 27. If sensitivity is undefined, then
// a. If usage is "sort", then
// i. Let sensitivity be "variant".
// b. Else,
// i. Let dataLocale be r.[[dataLocale]].
// ii. Let dataLocaleData be localeData.[[<dataLocale>]].
// iii. Let sensitivity be dataLocaleData.[[sensitivity]].
.or_else(|| (usage == Usage::Sort).then_some(Sensitivity::Variant));
let sensitivity = get_option(&options, utf16!("sensitivity"), context)?
// 27. If sensitivity is undefined, then
// a. If usage is "sort", then
// i. Let sensitivity be "variant".
// b. Else,
// i. Let dataLocale be r.[[dataLocale]].
// ii. Let dataLocaleData be localeData.[[<dataLocale>]].
// iii. Let sensitivity be dataLocaleData.[[sensitivity]].
.or_else(|| (usage == Usage::Sort).then_some(Sensitivity::Variant));

// 29. Let ignorePunctuation be ? GetOption(options, "ignorePunctuation", boolean, empty, false).
// 30. Set collator.[[IgnorePunctuation]] to ignorePunctuation.
let ignore_punctuation =
get_option::<bool>(&options, utf16!("ignorePunctuation"), false, context)?
.unwrap_or_default();
let ignore_punctuation: bool =
get_option(&options, utf16!("ignorePunctuation"), context)?.unwrap_or_default();

let (strength, case_level) = sensitivity.map(Sensitivity::to_collator_options).unzip();

Expand Down
12 changes: 4 additions & 8 deletions boa_engine/src/builtins/intl/list_format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{

use super::{
locale::{canonicalize_locale_list, resolve_locale, supported_locales},
options::{IntlOptions, LocaleMatcher},
options::IntlOptions,
Service,
};

Expand Down Expand Up @@ -111,9 +111,7 @@ impl BuiltInConstructor for ListFormat {

// 5. Let opt be a new Record.
// 6. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
let matcher =
get_option::<LocaleMatcher>(&options, utf16!("localeMatcher"), false, context)?
.unwrap_or_default();
let matcher = get_option(&options, utf16!("localeMatcher"), context)?.unwrap_or_default();

// 7. Set opt.[[localeMatcher]] to matcher.
// 8. Let localeData be %ListFormat%.[[LocaleData]].
Expand All @@ -130,13 +128,11 @@ impl BuiltInConstructor for ListFormat {

// 11. Let type be ? GetOption(options, "type", string, « "conjunction", "disjunction", "unit" », "conjunction").
// 12. Set listFormat.[[Type]] to type.
let typ = get_option::<ListFormatType>(&options, utf16!("type"), false, context)?
.unwrap_or_default();
let typ = get_option(&options, utf16!("type"), context)?.unwrap_or_default();

// 13. Let style be ? GetOption(options, "style", string, « "long", "short", "narrow" », "long").
// 14. Set listFormat.[[Style]] to style.
let style = get_option::<ListLength>(&options, utf16!("style"), false, context)?
.unwrap_or(ListLength::Wide);
let style = get_option(&options, utf16!("style"), context)?.unwrap_or(ListLength::Wide);

// 15. Let dataLocale be r.[[dataLocale]].
// 16. Let dataLocaleData be localeData.[[<dataLocale>]].
Expand Down
63 changes: 23 additions & 40 deletions boa_engine/src/builtins/intl/locale/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ use boa_profiler::Profiler;
use icu_collator::CaseFirst;
use icu_datetime::options::preferences::HourCycle;
use icu_locid::{
extensions::unicode::Value,
extensions_unicode_key as key, extensions_unicode_value as value,
subtags::{Language, Region, Script},
extensions::unicode::Value, extensions_unicode_key as key, extensions_unicode_value as value,
};

#[cfg(test)]
Expand Down Expand Up @@ -237,27 +235,18 @@ impl BuiltInConstructor for Locale {
// 3. If ! IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
// 4. Let language be ? GetOption(options, "language", string, empty, undefined).
// 5. If language is not undefined, then
let language = get_option::<JsString>(options, utf16!("language"), false, context)?
// a. If language does not match the unicode_language_subtag production, throw a RangeError exception.
.map(|s| s.to_std_string_escaped().parse::<Language>())
.transpose()
.map_err(|e| JsNativeError::range().with_message(e.to_string()))?;
// a. If language does not match the unicode_language_subtag production, throw a RangeError exception.
let language = get_option(options, utf16!("language"), context)?;

// 6. Let script be ? GetOption(options, "script", string, empty, undefined).
// 7. If script is not undefined, then
let script = get_option::<JsString>(options, utf16!("script"), false, context)?
.map(|s| s.to_std_string_escaped().parse::<Script>())
.transpose()
// a. If script does not match the unicode_script_subtag production, throw a RangeError exception.
.map_err(|e| JsNativeError::range().with_message(e.to_string()))?;
// a. If script does not match the unicode_script_subtag production, throw a RangeError exception.
let script = get_option(options, utf16!("script"), context)?;

// 8. Let region be ? GetOption(options, "region", string, empty, undefined).
// 9. If region is not undefined, then
let region = get_option::<JsString>(options, utf16!("region"), false, context)?
.map(|s| s.to_std_string_escaped().parse::<Region>())
.transpose()
// a. If region does not match the unicode_region_subtag production, throw a RangeError exception.
.map_err(|e| JsNativeError::range().with_message(e.to_string()))?;
// a. If region does not match the unicode_region_subtag production, throw a RangeError exception.
let region = get_option(options, utf16!("region"), context)?;

// 10. Set tag to ! CanonicalizeUnicodeLocaleId(tag).
context.icu().locale_canonicalizer().canonicalize(&mut tag);
Expand Down Expand Up @@ -299,42 +288,36 @@ impl BuiltInConstructor for Locale {
// 14. If calendar is not undefined, then
// 15. Set opt.[[ca]] to calendar.
// a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
let ca = get_option::<Value>(options, utf16!("calendar"), false, context)?;
let ca = get_option(options, utf16!("calendar"), context)?;

// 16. Let collation be ? GetOption(options, "collation", string, empty, undefined).
// 17. If collation is not undefined, then
// 18. Set opt.[[co]] to collation.
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
let co = get_option::<Value>(options, utf16!("collation"), false, context)?;
let co = get_option(options, utf16!("collation"), context)?;

// 19. Let hc be ? GetOption(options, "hourCycle", string, « "h11", "h12", "h23", "h24" », undefined).
// 20. Set opt.[[hc]] to hc.
let hc =
get_option::<HourCycle>(options, utf16!("hourCycle"), false, context)?.map(
|hc| match hc {
HourCycle::H24 => value!("h24"),
HourCycle::H23 => value!("h23"),
HourCycle::H12 => value!("h12"),
HourCycle::H11 => value!("h11"),
},
);
let hc = get_option(options, utf16!("hourCycle"), context)?.map(|hc| match hc {
HourCycle::H24 => value!("h24"),
HourCycle::H23 => value!("h23"),
HourCycle::H12 => value!("h12"),
HourCycle::H11 => value!("h11"),
});

// 21. Let kf be ? GetOption(options, "caseFirst", string, « "upper", "lower", "false" », undefined).
// 22. Set opt.[[kf]] to kf.
let kf =
get_option::<CaseFirst>(options, utf16!("caseFirst"), false, context)?.map(
|kf| match kf {
CaseFirst::UpperFirst => value!("upper"),
CaseFirst::LowerFirst => value!("lower"),
CaseFirst::Off => value!("false"),
_ => unreachable!(),
},
);
let kf = get_option(options, utf16!("caseFirst"), context)?.map(|kf| match kf {
CaseFirst::UpperFirst => value!("upper"),
CaseFirst::LowerFirst => value!("lower"),
CaseFirst::Off => value!("false"),
_ => unreachable!(),
});

// 23. Let kn be ? GetOption(options, "numeric", boolean, empty, undefined).
// 24. If kn is not undefined, set kn to ! ToString(kn).
// 25. Set opt.[[kn]] to kn.
let kn = get_option::<bool>(options, utf16!("numeric"), false, context)?.map(|b| {
let kn = get_option(options, utf16!("numeric"), context)?.map(|b| {
if b {
value!("true")
} else {
Expand All @@ -346,7 +329,7 @@ impl BuiltInConstructor for Locale {
// 27. If numberingSystem is not undefined, then
// 28. Set opt.[[nu]] to numberingSystem.
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
let nu = get_option::<Value>(options, utf16!("numberingSystem"), false, context)?;
let nu = get_option(options, utf16!("numberingSystem"), context)?;

// 29. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys).
// 30. Set locale.[[Locale]] to r.[[locale]].
Expand Down
48 changes: 39 additions & 9 deletions boa_engine/src/builtins/intl/locale/options.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,51 @@
use icu_locid::extensions::unicode::Value;
use icu_locid::{
extensions::unicode::Value,
subtags::{Language, Region, Script},
};

use crate::{builtins::options::OptionType, Context, JsNativeError};

impl OptionType for Value {
fn from_value(value: crate::JsValue, context: &mut Context<'_>) -> crate::JsResult<Self> {
let val = value
.to_string(context)?
.to_std_string_escaped()
.parse::<Self>()
.map_err(|e| JsNativeError::range().with_message(e.to_string()))?;
let val = value.to_string(context)?.to_std_string_escaped();

if val.as_tinystr_slice().is_empty() {
if val.len() < 3 {
return Err(JsNativeError::range()
.with_message("Unicode Locale Identifier `type` cannot be empty")
.with_message("nonterminal `type` must be at least 3 characters long")
.into());
}

Ok(val)
val.parse::<Self>()
.map_err(|e| JsNativeError::range().with_message(e.to_string()).into())
}
}

impl OptionType for Language {
fn from_value(value: crate::JsValue, context: &mut Context<'_>) -> crate::JsResult<Self> {
value
.to_string(context)?
.to_std_string_escaped()
.parse::<Self>()
.map_err(|e| JsNativeError::range().with_message(e.to_string()).into())
}
}

impl OptionType for Script {
fn from_value(value: crate::JsValue, context: &mut Context<'_>) -> crate::JsResult<Self> {
value
.to_string(context)?
.to_std_string_escaped()
.parse::<Self>()
.map_err(|e| JsNativeError::range().with_message(e.to_string()).into())
}
}

impl OptionType for Region {
fn from_value(value: crate::JsValue, context: &mut Context<'_>) -> crate::JsResult<Self> {
value
.to_string(context)?
.to_std_string_escaped()
.parse::<Self>()
.map_err(|e| JsNativeError::range().with_message(e.to_string()).into())
}
}
3 changes: 1 addition & 2 deletions boa_engine/src/builtins/intl/locale/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,8 +546,7 @@ where
let options = coerce_options_to_object(options, context)?;

// 2. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
let matcher = get_option::<LocaleMatcher>(&options, utf16!("localeMatcher"), false, context)?
.unwrap_or_default();
let matcher = get_option(&options, utf16!("localeMatcher"), context)?.unwrap_or_default();

let elements = match matcher {
// 4. Else,
Expand Down
7 changes: 3 additions & 4 deletions boa_engine/src/builtins/intl/number_format/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub(crate) fn get_digit_format_options(

// 7. Let roundingPriority be ? GetOption(options, "roundingPriority", string, « "auto", "morePrecision", "lessPrecision" », "auto").
let mut rounding_priority =
get_option(options, utf16!("roundingPriority"), false, context)?.unwrap_or_default();
get_option(options, utf16!("roundingPriority"), context)?.unwrap_or_default();

// 8. Let roundingIncrement be ? GetNumberOption(options, "roundingIncrement", 1, 5000, 1).
// 9. If roundingIncrement is not in « 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 », throw a RangeError exception.
Expand All @@ -58,12 +58,11 @@ pub(crate) fn get_digit_format_options(
}

// 10. Let roundingMode be ? GetOption(options, "roundingMode", string, « "ceil", "floor", "expand", "trunc", "halfCeil", "halfFloor", "halfExpand", "halfTrunc", "halfEven" », "halfExpand").
let rounding_mode =
get_option(options, utf16!("roundingMode"), false, context)?.unwrap_or_default();
let rounding_mode = get_option(options, utf16!("roundingMode"), context)?.unwrap_or_default();

// 11. Let trailingZeroDisplay be ? GetOption(options, "trailingZeroDisplay", string, « "auto", "stripIfInteger" », "auto").
let trailing_zero_display =
get_option(options, utf16!("trailingZeroDisplay"), false, context)?.unwrap_or_default();
get_option(options, utf16!("trailingZeroDisplay"), context)?.unwrap_or_default();

// 12. NOTE: All fields required by SetNumberFormatDigitOptions have now been read from options. The remainder of this AO interprets the options and may throw exceptions.

Expand Down
10 changes: 4 additions & 6 deletions boa_engine/src/builtins/intl/plural_rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use super::{
f64_to_formatted_fixed_decimal, get_digit_format_options, DigitFormatOptions, Extrema,
Notation,
},
options::{coerce_options_to_object, IntlOptions, LocaleMatcher},
options::{coerce_options_to_object, IntlOptions},
Service,
};

Expand Down Expand Up @@ -113,14 +113,12 @@ impl BuiltInConstructor for PluralRules {
// 3. Let opt be a new Record.
// 4. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
// 5. Set opt.[[localeMatcher]] to matcher.
let matcher =
get_option::<LocaleMatcher>(&options, utf16!("localeMatcher"), false, context)?
.unwrap_or_default();
let matcher = get_option(&options, utf16!("localeMatcher"), context)?.unwrap_or_default();

// 6. Let t be ? GetOption(options, "type", string, « "cardinal", "ordinal" », "cardinal").
// 7. Set pluralRules.[[Type]] to t.
let rule_type = get_option::<PluralRuleType>(&options, utf16!("type"), false, context)?
.unwrap_or(PluralRuleType::Cardinal);
let rule_type =
get_option(&options, utf16!("type"), context)?.unwrap_or(PluralRuleType::Cardinal);

// 8. Perform ? SetNumberFormatDigitOptions(pluralRules, options, +0𝔽, 3𝔽, "standard").
let format_options = get_digit_format_options(&options, 0, 3, Notation::Standard, context)?;
Expand Down
10 changes: 3 additions & 7 deletions boa_engine/src/builtins/intl/segmenter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub(crate) use segments::*;

use super::{
locale::{canonicalize_locale_list, resolve_locale, supported_locales},
options::{IntlOptions, LocaleMatcher},
options::IntlOptions,
Service,
};

Expand Down Expand Up @@ -133,9 +133,7 @@ impl BuiltInConstructor for Segmenter {

// 6. Let opt be a new Record.
// 7. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
let matcher =
get_option::<LocaleMatcher>(&options, utf16!("localeMatcher"), false, context)?
.unwrap_or_default();
let matcher = get_option(&options, utf16!("localeMatcher"), context)?.unwrap_or_default();

// 8. Set opt.[[localeMatcher]] to matcher.
// 9. Let localeData be %Segmenter%.[[LocaleData]].
Expand All @@ -151,9 +149,7 @@ impl BuiltInConstructor for Segmenter {
);

// 12. Let granularity be ? GetOption(options, "granularity", string, « "grapheme", "word", "sentence" », "grapheme").
let granularity =
get_option::<Granularity>(&options, utf16!("granularity"), false, context)?
.unwrap_or_default();
let granularity = get_option(&options, utf16!("granularity"), context)?.unwrap_or_default();
// 13. Set segmenter.[[SegmenterGranularity]] to granularity.

let native = match granularity {
Expand Down
Loading
Loading