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

BREAKING: Added Rule-Based Number Format Static API #46

Merged
merged 85 commits into from
Apr 2, 2023

Conversation

NightOwl888
Copy link
Owner

@NightOwl888 NightOwl888 commented Apr 2, 2023

Closes #41.

This redesigns the RuleBasedNumberFormat and PluralFormat classes into static methods that replace the former implementation. The mapping old-to-new is as follows:

  1. ICU4N.Text.RuleBasedNumberFormat
    a. Rules Engine > ICU4N.Globalization.NumberFormatRules, an immutable class. The instances for SpellOut, Ordinal, Duration, and NumberingSystem are available as properties on the UNumberFormatInfo class which is returned from the UCultureInfo.NumberFormat property.
    b. Format method overloads > overloads of ICU4N.FormatNumberRuleBased.ToString() and ICU4N.FormatNumberRuleBased.TryFormat(), which are also also extension methods for all built-in .NET numeric data types.
  2. ICU4N.Text.DecimalFormatSymbols > ICU4N.Globalization.UNumberFormatInfo, which is available from the UCultureInfo.NumberFormat property.
  3. ICU4N.Text.NFRule > ICU4N.Globalization.NumberFormatRule.
  4. ICU4N.Text.NFRuleSet > ICU4N.Globalization.NumberFormatRuleSet.
  5. ICU4N.Text.NFSubstitution > ICU4N.Globalization.Substitution. All subclasses have also been copied to the ICU4N.Globalization namespace with their original names to subclass the new base class.

As a stand-in for DecimalFormat, we are using the custom formatting string feature in .NET. But since the .NET formatter doesn't support all of the settings that DecimalFormat has, these have been hidden from the public API until a complete implementation of DecimalFormat is constructed.

PluralFormat is also not available publicly as the MessagePattern class will need some refactoring to avoid unnecessary heap allocations.

This functionality is also currently only available on .NET 6+.

The old ICU4J APIs have been removed from the public API for NuGet releases. They can be enabled for custom builds by setting the MSBuild property IncludeLegacyNumberFormat=true in the build. Alternatively, this API is available in the https://www.nuget.org/packages/ICU4N/60.1.0-alpha.401 package. Do note there are known issues with rounding accuracy in this implementation of DecimalFormat.

The .NET formatter does not follow the IEEE 754 spec for rounding - it rounds toward positive infinity rather than to the nearest even number. So there may be issues with rounding in this new formatter for floating point types which will be addressed when we replace DecimalFormat.

… note about using Math.Round() instead of Math.Ceiling() because the Java default is ToPositiveInfinity (the equivalent of Math.Ceiling), but the tests only pass with this configuration
…since we don't use any linked list functionality
…number formats using the .NET formatter as a replacement for DecimalFormat.
…values that are matched with PatternProps.IsWhiteSpace() for use in Trim() method
… rule text into rule/rule set/substitution objects. Also sealed all non-inheritable classes, enabled nullable reference type support, and added guard clauses, where appropriate.
…instead of PluralRules, since PluralRules are culture data dependent.
…umerator): Added features to control delimiter length to exclude from the token and trim behavior for start/end/both (or specify no trimChars for no trimming)
…state is equivalent between RuleBasedNumberFormat and NumberFormatRules with the same input string and fixed several bugs in the parser.
…cally so it doesn't have to be parsed on every request.
…nd to startIndex/length to match .NET conventions. Optimized to use ValueStringBuilder, where Span<T> is supported.
…sembly, bool) and LocaleID property visible internally (as well as protected)
… method to create an instance from UCultureInfo/NumberPresentation.
… Added functionality to load and cache resource data in UCultureData and integrated it with UCultureInfo and UNumberFormatInfo.
…cached copy of UCultureInfo when creating the culture list
…ce() that accepts cultureName (locale baseName) as a string
… Changed the values to start with 0 instead of 1 so we have a reasonable default value in .NET.
…uilder parameter and fixed the insert operation of pluralization in NumberFormatRule to happen entirely on the stack (if possible).
…le based formatting to 128 chars to cover most cases on the stack.
…se correct override values when formatting numbers (based on where the original DecimalFormat instances got their setting values)
…als, GetHashCode, ToString(), and DefaultRuleSetName
…) extension methods and build errors due the unsafe logic in PluralRules.
…method to quickly lookup the NumberingSystemRules instance for the current UNumberFormatInfo.
…p for current context. We no longer store these rules in the nonNumericalRules array, they are in the fractionRules field instead. We get them using the GetBestFractionRule() method and supplying the fraction rule index from NumberFormatRule.
…) and TryFormat() overloads for every numeric data type.
…rked APIs internal that are not yet in use (such as properties for currency and percentage formatting). Implemented the missing ReadOnly() method.
…entations and added API documentation for NumberFormat, IsReadOnly, ReadOnly() and Clone() members.
… method. This is in .NET only to allow it to fetch culture settings that have changed in the underlying OS.
…ternal, for now. This won't be very useful until after we have public overloads of the format/parse operations that accept an instance of this.
…instance so we don't fill up the UCultureData cache with all cultures and non-culture resource names.
…ntextExtensions): Removed from the public API since they had been previously refactored in the Globalization namespace as Capitalization, DialectHandling, DisplayLength, and DisplayLength enums and the DisplayContextOptions class
…ormat): Removed from the public API and added an IncludeLegacyNumberFormat build property so they can be optionally compiled for those who need these features. The plan is to port them into static APIs later.
…rrected jargon error from transient > transitive dependencies.
…he names as they were in ICU4J, since this adds clarity to their intended purpose. Also explicitly specified numeric values of all DisplayContext enums in ICU4N.Globalization to match ICU4J.
@NightOwl888 NightOwl888 merged commit 1545efb into main Apr 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Spellout numbering
1 participant