icu4x
icu4x copied to clipboard
Add explicit cases to `PluralCategory`
trafficstars
Explicit 0 and 1 cases are required by patterns in multiple components.
- @robertbastian worried if we don't put in the enum, every caller of PluralElements you will forget to check for the specific cases (if you only handle general cases).
- @sffc You should have a new enum:
enum PluralCategoryExtended {
PluralCategory(PluralCategory),
Explicit0,
Explicit1,
}
impl PluralRules {
pub fn select_from_plural_elements<T>(&self, op: PluralOperands, choices: &PluralElements<T>) -> T {
let category = self.category_for(op);
if op.is_exactly_one() {
if let Some(value) = choices.get_explicit1() {
return value;
}
}
// same for zero
choices.get(category)
}
/*
pub fn select_with_explicit(&self, op: PluralOperands) -> (Option<Explicit>, PluralCategory) {
let category = self.category_for(op);
if op.is_exactly_one() {
if let Some(value) = choices.get_explicit1() {
return (Some(Explicit::One), category);
}
}
// same for zero
(None, category)
// ...
}
*/
}
// in icu::plurals
pub struct PluralElements<'a, T: ?Sized> {
pub other: &'a T,
pub zero: Option<&'a T>,
// ...
}
// in icu::plurals::provider
impl PluralElementsV1<T> {
pub fn get(&self, op: PluralOperands, rules: &PluralRules) -> &T {
let category = rules.category_for(op);
if op.is_exactly_zero() {
if let Some(value) = self.get_explicit0() {
return value;
}
}
if op.is_exactly_one() {
if let Some(value) = self.get_explicit1() {
return value;
}
}
self.get(category)
}
pub fn new(builder: PluralElements<T>) -> Self where T: PartialEq {}
}
- @robertbastian I've been working with a new struct named PluralElements; could that be the argument?
- @robertbastian
PluralCategoryExtendedwould need to berepr(u8) - @Manishearth We could make that the public interface and have a
repr(u8)internal enum - @robertbastian For now it can be private
- @younies So do we change call sites from
PluralCategorytoPluralCategoryExtended? - @robertbastian We need to change call sites so pass
PluralOperandsandPluralRulesinstead of a preresolvedPluralCategory - @younies I believe in
CurrencyCompact, you fallback for other if other doesn't exist. Then you go to the display name - @robertbastian - If other doesn't exist, none of the cases exist and you cannot construct a
PluralElements - @robertbastian for current constructors for
PluralElements, you pass inOptions for everything - @sffc We should make the constructor be non-exhaustive so we can add more explicit cases
- @robertbastian That's not defined in CLDR, leads to less optimization if it's non exhaustive. This is going to be used everywhere, we should really optimize
- @sffc May not be the case in the future. It should be just as easy to support 2 as we could support 5 cases. I think we can cap it at 4 bits (16 variants)
- @sffc Or maybe
PluralElementsV1should just be theVarULEofPluralElements? - @robertbastian Is it okay for
PluralElementsV1to deduplicate and not round-trip? - @Manishearth Equality?
- @robertbastian We can write custom Eq impls.
- @manishearth - then yes
- @sffc Should it be called
PluralElementsBorrowed? - @robertbastian I don't think there should be an owned version because it is just a plural arguments bag.
Decision:
- Create
icu::plurals::PluralElements, a non-exhaustive struct with a bunch of Option fields PluralRulesgets a function that processesPluralElements- Create
icu::plurals::provider::PluralElementsV1, a data struct that represents the same data in a more compact way, with private fields - We will migrate
PluralElementsV1to https://github.com/unicode-org/icu4x/issues/5378. Unclear whether we will makePluralElementsV1itself a VarULE or make a separate VarULE. PluralElementsV1gets a function that takes a&PluralRulesand could have a more optimized algorithm, or could internally convert toPluralElements
LGTM: @robertbastian @sffc