/* * Copyright (c) 2021-2024, Tim Flynn <trflynn89@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include <AK/Optional.h> #include <AK/String.h> #include <AK/StringView.h> #include <AK/Variant.h> #include <AK/Vector.h> #include <LibUnicode/Forward.h> #include <LibUnicode/PluralRules.h> namespace Unicode { enum class NumberFormatStyle { Decimal, Percent, Currency, Unit, }; NumberFormatStyle number_format_style_from_string(StringView); StringView number_format_style_to_string(NumberFormatStyle); enum class SignDisplay { Auto, Never, Always, ExceptZero, Negative, }; SignDisplay sign_display_from_string(StringView); StringView sign_display_to_string(SignDisplay); enum class Notation { Standard, Scientific, Engineering, Compact, }; Notation notation_from_string(StringView); StringView notation_to_string(Notation); enum class CompactDisplay { Short, Long, }; CompactDisplay compact_display_from_string(StringView); StringView compact_display_to_string(CompactDisplay); enum class Grouping { Always, Auto, Min2, False, }; Grouping grouping_from_string(StringView); StringView grouping_to_string(Grouping); enum class CurrencyDisplay { Code, Symbol, NarrowSymbol, Name, }; CurrencyDisplay currency_display_from_string(StringView); StringView currency_display_to_string(CurrencyDisplay); enum class CurrencySign { Standard, Accounting, }; CurrencySign currency_sign_from_string(StringView); StringView currency_sign_to_string(CurrencySign); struct DisplayOptions { NumberFormatStyle style { NumberFormatStyle::Decimal }; SignDisplay sign_display { SignDisplay::Auto }; Notation notation { Notation::Standard }; Optional<CompactDisplay> compact_display; Grouping grouping { Grouping::Always }; Optional<String> currency; Optional<CurrencyDisplay> currency_display; Optional<CurrencySign> currency_sign; Optional<String> unit; Optional<Style> unit_display; }; enum class RoundingType { SignificantDigits, FractionDigits, MorePrecision, LessPrecision, }; RoundingType rounding_type_from_string(StringView); StringView rounding_type_to_string(RoundingType); enum class RoundingMode { Ceil, Expand, Floor, HalfCeil, HalfEven, HalfExpand, HalfFloor, HalfTrunc, Trunc, }; RoundingMode rounding_mode_from_string(StringView); StringView rounding_mode_to_string(RoundingMode); enum class TrailingZeroDisplay { Auto, StripIfInteger, }; TrailingZeroDisplay trailing_zero_display_from_string(StringView); StringView trailing_zero_display_to_string(TrailingZeroDisplay); struct RoundingOptions { RoundingType type { RoundingType::MorePrecision }; RoundingMode mode { RoundingMode::HalfExpand }; TrailingZeroDisplay trailing_zero_display { TrailingZeroDisplay::Auto }; Optional<int> min_significant_digits; Optional<int> max_significant_digits; Optional<int> min_fraction_digits; Optional<int> max_fraction_digits; int min_integer_digits { 0 }; int rounding_increment { 1 }; }; class NumberFormat { public: static NonnullOwnPtr<NumberFormat> create( StringView locale, DisplayOptions const&, RoundingOptions const&); virtual ~NumberFormat() = default; struct Partition { StringView type; String value; StringView source; }; using Value = Variant<double, String>; virtual String format(Value const&) const = 0; virtual String format_to_decimal(Value const&) const = 0; virtual Vector<Partition> format_to_parts(Value const&) const = 0; virtual String format_range(Value const&, Value const&) const = 0; virtual Vector<Partition> format_range_to_parts(Value const&, Value const&) const = 0; virtual void create_plural_rules(PluralForm) = 0; virtual PluralCategory select_plural(double) const = 0; virtual PluralCategory select_plural_range(double, double) const = 0; virtual Vector<PluralCategory> available_plural_categories() const = 0; protected: NumberFormat() = default; }; }