mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 05:48:12 +00:00
LibUnicode: Replace NumberFormat::Plurality with Unicode::PluralCategory
To prepare for using plural rules within number & duration format, this removes the NumberFormat::Plurality enumeration. This also adds PluralCategory::ExactlyZero & PluralCategory::ExactlyOne. These are used in locales like French, where PluralCategory::One really means any value from 0.00 to 1.99. PluralCategory::ExactlyOne means only the value 1, as the name implies. These exact rules are not known by the general plural rules, they are explicitly for number / currency format.
This commit is contained in:
parent
cc5c707649
commit
232df4196b
3 changed files with 26 additions and 40 deletions
|
@ -29,6 +29,7 @@
|
||||||
#include <LibJS/Runtime/Intl/AbstractOperations.h>
|
#include <LibJS/Runtime/Intl/AbstractOperations.h>
|
||||||
#include <LibUnicode/Locale.h>
|
#include <LibUnicode/Locale.h>
|
||||||
#include <LibUnicode/NumberFormat.h>
|
#include <LibUnicode/NumberFormat.h>
|
||||||
|
#include <LibUnicode/PluralRules.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
using StringIndexType = u16;
|
using StringIndexType = u16;
|
||||||
|
@ -57,29 +58,10 @@ enum class NumberFormatType {
|
||||||
struct NumberFormat : public Unicode::NumberFormat {
|
struct NumberFormat : public Unicode::NumberFormat {
|
||||||
using Base = Unicode::NumberFormat;
|
using Base = Unicode::NumberFormat;
|
||||||
|
|
||||||
static Base::Plurality plurality_from_string(StringView plurality)
|
|
||||||
{
|
|
||||||
if (plurality == "other"sv)
|
|
||||||
return Base::Plurality::Other;
|
|
||||||
if (plurality == "1"sv)
|
|
||||||
return Base::Plurality::Single;
|
|
||||||
if (plurality == "zero"sv)
|
|
||||||
return Base::Plurality::Zero;
|
|
||||||
if (plurality == "one"sv)
|
|
||||||
return Base::Plurality::One;
|
|
||||||
if (plurality == "two"sv)
|
|
||||||
return Base::Plurality::Two;
|
|
||||||
if (plurality == "few"sv)
|
|
||||||
return Base::Plurality::Few;
|
|
||||||
if (plurality == "many"sv)
|
|
||||||
return Base::Plurality::Many;
|
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned hash() const
|
unsigned hash() const
|
||||||
{
|
{
|
||||||
auto hash = pair_int_hash(magnitude, exponent);
|
auto hash = pair_int_hash(magnitude, exponent);
|
||||||
hash = pair_int_hash(hash, static_cast<u8>(plurality));
|
hash = pair_int_hash(hash, to_underlying(plurality));
|
||||||
hash = pair_int_hash(hash, zero_format_index);
|
hash = pair_int_hash(hash, zero_format_index);
|
||||||
hash = pair_int_hash(hash, positive_format_index);
|
hash = pair_int_hash(hash, positive_format_index);
|
||||||
hash = pair_int_hash(hash, negative_format_index);
|
hash = pair_int_hash(hash, negative_format_index);
|
||||||
|
@ -118,7 +100,7 @@ struct AK::Formatter<NumberFormat> : Formatter<FormatString> {
|
||||||
"{{ {}, {}, {}, {}, {}, {}, {{ {} }} }}",
|
"{{ {}, {}, {}, {}, {}, {}, {{ {} }} }}",
|
||||||
format.magnitude,
|
format.magnitude,
|
||||||
format.exponent,
|
format.exponent,
|
||||||
static_cast<u8>(format.plurality),
|
to_underlying(format.plurality),
|
||||||
format.zero_format_index,
|
format.zero_format_index,
|
||||||
format.positive_format_index,
|
format.positive_format_index,
|
||||||
format.negative_format_index,
|
format.negative_format_index,
|
||||||
|
@ -496,7 +478,7 @@ static ErrorOr<void> parse_number_systems(String locale_numbers_path, UnicodeLoc
|
||||||
VERIFY(split_key[0] == "unitPattern"sv);
|
VERIFY(split_key[0] == "unitPattern"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
format.plurality = NumberFormat::plurality_from_string(split_key[2]);
|
format.plurality = Unicode::plural_category_from_string(split_key[2]);
|
||||||
parse_number_pattern(move(patterns), locale_data, NumberFormatType::Compact, format);
|
parse_number_pattern(move(patterns), locale_data, NumberFormatType::Compact, format);
|
||||||
|
|
||||||
auto format_index = locale_data.unique_formats.ensure(move(format));
|
auto format_index = locale_data.unique_formats.ensure(move(format));
|
||||||
|
@ -675,7 +657,7 @@ static ErrorOr<void> parse_units(String locale_units_path, UnicodeLocaleData& lo
|
||||||
NumberFormat format {};
|
NumberFormat format {};
|
||||||
|
|
||||||
auto plurality = unit_key.substring_view(unit_pattern_prefix.length());
|
auto plurality = unit_key.substring_view(unit_pattern_prefix.length());
|
||||||
format.plurality = NumberFormat::plurality_from_string(plurality);
|
format.plurality = Unicode::plural_category_from_string(plurality);
|
||||||
|
|
||||||
auto zero_format = pattern_value.as_string().replace("{0}"sv, "{number}"sv, ReplaceMode::FirstOnly);
|
auto zero_format = pattern_value.as_string().replace("{0}"sv, "{number}"sv, ReplaceMode::FirstOnly);
|
||||||
zero_format = parse_identifiers(zero_format, "unitIdentifier"sv, locale_data, format);
|
zero_format = parse_identifiers(zero_format, "unitIdentifier"sv, locale_data, format);
|
||||||
|
@ -807,6 +789,7 @@ static ErrorOr<void> generate_unicode_locale_implementation(Core::Stream::Buffer
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibUnicode/Locale.h>
|
#include <LibUnicode/Locale.h>
|
||||||
#include <LibUnicode/NumberFormat.h>
|
#include <LibUnicode/NumberFormat.h>
|
||||||
|
#include <LibUnicode/PluralRules.h>
|
||||||
#include <LibUnicode/UnicodeLocale.h>
|
#include <LibUnicode/UnicodeLocale.h>
|
||||||
#include <LibUnicode/UnicodeNumberFormat.h>
|
#include <LibUnicode/UnicodeNumberFormat.h>
|
||||||
|
|
||||||
|
@ -822,7 +805,7 @@ struct NumberFormatImpl {
|
||||||
|
|
||||||
number_format.magnitude = magnitude;
|
number_format.magnitude = magnitude;
|
||||||
number_format.exponent = exponent;
|
number_format.exponent = exponent;
|
||||||
number_format.plurality = static_cast<NumberFormat::Plurality>(plurality);
|
number_format.plurality = static_cast<PluralCategory>(plurality);
|
||||||
number_format.zero_format = s_string_list[zero_format];
|
number_format.zero_format = s_string_list[zero_format];
|
||||||
number_format.positive_format = s_string_list[positive_format];
|
number_format.positive_format = s_string_list[positive_format];
|
||||||
number_format.negative_format = s_string_list[negative_format];
|
number_format.negative_format = s_string_list[negative_format];
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibUnicode/Forward.h>
|
#include <LibUnicode/Forward.h>
|
||||||
|
#include <LibUnicode/PluralRules.h>
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Unicode {
|
||||||
|
|
||||||
|
@ -36,19 +37,9 @@ enum class CompactNumberFormatType : u8 {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NumberFormat {
|
struct NumberFormat {
|
||||||
enum class Plurality : u8 {
|
|
||||||
Other,
|
|
||||||
Zero,
|
|
||||||
Single,
|
|
||||||
One,
|
|
||||||
Two,
|
|
||||||
Few,
|
|
||||||
Many,
|
|
||||||
};
|
|
||||||
|
|
||||||
u8 magnitude { 0 };
|
u8 magnitude { 0 };
|
||||||
u8 exponent { 0 };
|
u8 exponent { 0 };
|
||||||
Plurality plurality { Plurality::Other };
|
PluralCategory plurality { PluralCategory::Other };
|
||||||
StringView zero_format {};
|
StringView zero_format {};
|
||||||
StringView positive_format {};
|
StringView positive_format {};
|
||||||
StringView negative_format {};
|
StringView negative_format {};
|
||||||
|
@ -94,20 +85,20 @@ Optional<FormatType> select_pattern_with_plurality(Vector<FormatType> const& for
|
||||||
};
|
};
|
||||||
|
|
||||||
if (number == 0) {
|
if (number == 0) {
|
||||||
if (auto patterns = find_plurality(FormatType::Plurality::Zero); patterns.has_value())
|
if (auto patterns = find_plurality(PluralCategory::Zero); patterns.has_value())
|
||||||
return patterns;
|
return patterns;
|
||||||
} else if (number == 1) {
|
} else if (number == 1) {
|
||||||
if (auto patterns = find_plurality(FormatType::Plurality::One); patterns.has_value())
|
if (auto patterns = find_plurality(PluralCategory::One); patterns.has_value())
|
||||||
return patterns;
|
return patterns;
|
||||||
} else if (number == 2) {
|
} else if (number == 2) {
|
||||||
if (auto patterns = find_plurality(FormatType::Plurality::Two); patterns.has_value())
|
if (auto patterns = find_plurality(PluralCategory::Two); patterns.has_value())
|
||||||
return patterns;
|
return patterns;
|
||||||
} else if (number > 2) {
|
} else if (number > 2) {
|
||||||
if (auto patterns = find_plurality(FormatType::Plurality::Many); patterns.has_value())
|
if (auto patterns = find_plurality(PluralCategory::Many); patterns.has_value())
|
||||||
return patterns;
|
return patterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
return find_plurality(FormatType::Plurality::Other);
|
return find_plurality(PluralCategory::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,10 @@ enum class PluralCategory : u8 {
|
||||||
Two,
|
Two,
|
||||||
Few,
|
Few,
|
||||||
Many,
|
Many,
|
||||||
|
|
||||||
|
// https://unicode.org/reports/tr35/tr35-numbers.html#Explicit_0_1_rules
|
||||||
|
ExactlyZero,
|
||||||
|
ExactlyOne,
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://unicode.org/reports/tr35/tr35-numbers.html#Plural_Operand_Meanings
|
// https://unicode.org/reports/tr35/tr35-numbers.html#Plural_Operand_Meanings
|
||||||
|
@ -81,6 +85,10 @@ constexpr PluralCategory plural_category_from_string(StringView category)
|
||||||
return PluralCategory::Few;
|
return PluralCategory::Few;
|
||||||
if (category == "many"sv)
|
if (category == "many"sv)
|
||||||
return PluralCategory::Many;
|
return PluralCategory::Many;
|
||||||
|
if (category == "0"sv)
|
||||||
|
return PluralCategory::ExactlyZero;
|
||||||
|
if (category == "1"sv)
|
||||||
|
return PluralCategory::ExactlyOne;
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +108,10 @@ constexpr StringView plural_category_to_string(PluralCategory category)
|
||||||
return "few"sv;
|
return "few"sv;
|
||||||
case PluralCategory::Many:
|
case PluralCategory::Many:
|
||||||
return "many"sv;
|
return "many"sv;
|
||||||
|
case PluralCategory::ExactlyZero:
|
||||||
|
return "0"sv;
|
||||||
|
case PluralCategory::ExactlyOne:
|
||||||
|
return "1"sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue