Add format parameter to Decimal.parse (#11205)

This commit is contained in:
Gregory Michael Travis 2024-10-01 14:55:40 -04:00 committed by GitHub
parent 0b8a0c493a
commit 3a22147eaf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 38 additions and 11 deletions

View File

@ -64,7 +64,8 @@
- [Added .floor, .ceil, .trunc to the in-memory `Decimal` column.][10887]
- [Added vectorized .round to the in-memory `Decimal` column.][10912]
- [`select_into_database_table` no longer defaults the primary key to the first
column][11120]
column.][11120]
- [Added `format` parameter to `Decimal.parse`.][11205]
[10614]: https://github.com/enso-org/enso/pull/10614
[10660]: https://github.com/enso-org/enso/pull/10660
@ -77,6 +78,7 @@
[10887]: https://github.com/enso-org/enso/pull/10887
[10912]: https://github.com/enso-org/enso/pull/10912
[11120]: https://github.com/enso-org/enso/pull/11120
[11205]: https://github.com/enso-org/enso/pull/11205
#### Enso Language & Runtime

View File

@ -1116,10 +1116,13 @@ type Decimal
Arguments:
- text: The text to parse into a `Decimal`.
- locale: The locale that specifies the format to use when parsing.
- format: The Java-style format to use to parse the string.
! Error Conditions
- If `text` is incorrectly formatted, a `Number_Parse_Error` is thrown.
- If `format` is incorrectly formatted (or does not match the `locale`,
an `Illegal_Argument` is thrown.
> Example
Parse a `Decimal` with no local specifier.
@ -1144,11 +1147,21 @@ type Decimal
Decimal.parse "123.456.789,87654" locale=Locale.italy
# => 123456789.87654
parse : Text -> Locale | Nothing -> Decimal ! Number_Parse_Error
parse text locale:(Locale | Nothing)=Nothing -> Decimal ! Number_Parse_Error = case locale of
Nothing -> Decimal.from_text text
Locale.Value java_locale -> Panic.catch ParseException ((NumberFormat.getInstance java_locale).parse text) _->
Error.throw (Number_Parse_Error.Error text)
> Example
Parse a `Decimal` with an explicit negative number format.
Decimal.parse "(123,456,789.654)" format="###,###.##;(###,###.##)"
# => -123456789.654
parse : Text -> Locale | Nothing -> Decimal ! Number_Parse_Error ! Illegal_Argument
parse text locale:Locale=Locale.default format:Text="" -> Decimal ! Number_Parse_Error ! Illegal_Argument =
Illegal_Argument.handle_java_exception <|
# `getInstance` returns `DecimalFormat` or a subclass of `DecimalFormat`.
decimal_format = NumberFormat.getInstance locale.java_locale
decimal_format.applyLocalizedPattern format
decimal_format.setParseBigDecimal True
Panic.catch ParseException (Decimal.Value (decimal_format.parse text)) _->
Error.throw (Number_Parse_Error.Error text)
## PRIVATE
precision : Integer

View File

@ -798,14 +798,26 @@ add_specs suite_builder =
d.format format="#,##.##" locale=Locale.italy . should_equal "1.23.45.67.89,88"
group_builder.specify "should parse correctly" <|
Decimal.parse "123456789.87654" . should_equal 123456789.87654
Decimal.parse "123,456,789.87654" locale=Locale.default . should_equal 123456789.87654
Decimal.parse "123,456,789.87654" locale=Locale.us . should_equal 123456789.87654
Decimal.parse "123.456.789,87654" locale=Locale.italy . should_equal 123456789.87654
Decimal.parse "123,456,789.87654" . should_equal (dec "123456789.87654")
Decimal.parse "123.456.789,87654" locale=Locale.italy . should_equal (dec "123456789.87654")
Decimal.parse "123,456,789.88" format="#,###.##" . should_equal (dec "123456789.88")
Decimal.parse "123.456.789,88" format="#.###,##" locale=Locale.italy . should_equal (dec "123456789.88")
Decimal.parse "1,23,45,67,89.88" format="#,##.##" . should_equal (dec "123456789.88")
Decimal.parse "1.23.45.67.89,88" format="#.##,##" locale=Locale.italy . should_equal (dec "123456789.88")
Decimal.parse "123.456.789,88" format="#,###.##" locale=Locale.italy . should_fail_with Illegal_Argument
Decimal.parse "123,456,789.88" format="#.###,##" . should_fail_with Illegal_Argument
Decimal.parse "123,456,789.87654" locale=Locale.italy . should_equal 123.456
Decimal.parse "123.456.789,87654" locale=Locale.us . should_equal 123.456
Decimal.parse "123,456,789.87654" . should_fail_with Number_Parse_Error
Decimal.parse "123,456,789.654" format="###,###.##;-###,###.##" . should_equal 123456789.654
Decimal.parse "-123,456,789.654" format="###,###.##;-###,###.##" . should_equal -123456789.654
Decimal.parse "(123,456,789.654)" format="###,###.##;-###,###.##" . should_fail_with Number_Parse_Error
Decimal.parse "123,456,789.654" format="###,###.##;(###,###.##)" . should_equal 123456789.654
Decimal.parse "-123,456,789.654" format="###,###.##;(###,###.##)" . should_fail_with Number_Parse_Error
Decimal.parse "(123,456,789.654)" format="###,###.##;(###,###.##)" . should_equal -123456789.654
suite_builder.group "(Decimal_Spec) signs" group_builder->
group_builder.specify "should calculate abs correctly" <|