mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 10:21:41 +03:00
Deserialise large integer and decimals from JSON automatically. (#10463)
- Sort large integer and decimal JSON deserialization. - Change type to be Integer instead of BigInt for large integers. - Add tests. - Update Table viz. - Preserve white space in JSON viz. ![image](https://github.com/enso-org/enso/assets/4699705/48c83616-c0ed-4cb4-862a-34cd4fff09aa) ![image](https://github.com/enso-org/enso/assets/4699705/5bae9ccd-1d0f-4b70-aea5-d4cebc3d9df8)
This commit is contained in:
parent
c2c4b95116
commit
d65371096b
@ -29,6 +29,7 @@ const primitive = computed(() => {
|
||||
<style scoped>
|
||||
.string {
|
||||
color: darkgreen;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.number {
|
||||
color: darkgreen;
|
||||
|
@ -229,7 +229,7 @@ const numberFormat = new Intl.NumberFormat(undefined, {
|
||||
function formatNumber(params: ICellRendererParams) {
|
||||
const valueType = params.value?.type
|
||||
let value
|
||||
if (valueType === 'BigInt') {
|
||||
if (valueType === 'Integer') {
|
||||
value = BigInt(params.value?.value)
|
||||
} else if (valueType === 'Decimal') {
|
||||
value = Number(params.value?.value)
|
||||
|
@ -999,6 +999,12 @@ type Decimal
|
||||
scale : Integer
|
||||
scale self = self.big_decimal.scale
|
||||
|
||||
## PRIVATE
|
||||
with_scale : Integer -> Decimal
|
||||
private with_scale self new_scale:Integer =
|
||||
if self.scale == new_scale then self else
|
||||
Decimal.Value (self.big_decimal.setScale new_scale)
|
||||
|
||||
## PRIVATE
|
||||
unscaled_value : Integer
|
||||
unscaled_value self = self.big_decimal.unscaledValue
|
||||
|
@ -1,6 +1,7 @@
|
||||
import project.Any.Any
|
||||
import project.Data.Array.Array
|
||||
import project.Data.Array_Proxy.Array_Proxy
|
||||
import project.Data.Decimal.Decimal
|
||||
import project.Data.Map.Map
|
||||
import project.Data.Numbers.Float
|
||||
import project.Data.Numbers.Integer
|
||||
@ -413,9 +414,12 @@ make_enso object =
|
||||
js_object : JS_Object ->
|
||||
## Handle deserializing date and time types.
|
||||
type_name = js_object.get "type"
|
||||
parsed = if type_name == "Date" then Date.from js_object else
|
||||
if type_name == "Date_Time" then Date_Time.from js_object else
|
||||
if type_name == "Time_Of_Day" then Time_Of_Day.from js_object else
|
||||
js_object
|
||||
parsed = case type_name of
|
||||
"Date" -> Date.from js_object
|
||||
"Date_Time" -> Date_Time.from js_object
|
||||
"Time_Of_Day" -> Time_Of_Day.from js_object
|
||||
"Decimal" -> Decimal.from js_object
|
||||
"Integer" -> Integer.from js_object
|
||||
_ -> js_object
|
||||
|
||||
if parsed.is_error then js_object else parsed
|
||||
|
@ -2,6 +2,7 @@ import project.Any.Any
|
||||
import project.Data.Array.Array
|
||||
import project.Data.Array_Proxy.Array_Proxy
|
||||
import project.Data.Decimal.Decimal
|
||||
import project.Data.Numeric.Math_Context.Math_Context
|
||||
import project.Data.Json.JS_Object
|
||||
import project.Data.Json.Json
|
||||
import project.Data.Locale.Locale
|
||||
@ -13,6 +14,7 @@ import project.Data.Text.Text
|
||||
import project.Data.Text.Text_Sub_Range.Text_Sub_Range
|
||||
import project.Data.Vector.Vector
|
||||
import project.Error.Error
|
||||
import project.Errors.Illegal_Argument.Illegal_Argument
|
||||
import project.Errors.Deprecated.Deprecated
|
||||
import project.Meta
|
||||
import project.Nothing.Nothing
|
||||
@ -57,15 +59,32 @@ Number.to_js_object self = case self of
|
||||
## JS Safe Integer range -(2^53 - 1) to (2^53 - 1)
|
||||
js_max_integer = 9007199254740991
|
||||
if self >= -js_max_integer && self < js_max_integer then self else
|
||||
JS_Object.from_pairs [["type", "BigInt"], ["value", self.to_text]]
|
||||
JS_Object.from_pairs [["type", "Integer"], ["value", self.to_text]]
|
||||
_ -> self
|
||||
|
||||
## PRIVATE
|
||||
Converts a JS_Object to an Integer.
|
||||
Integer.from (that:JS_Object) =
|
||||
case that.get "type" == "Integer" && ["value"].all that.contains_key of
|
||||
True -> Integer.parse (that.at "value")
|
||||
False -> Error.throw (Illegal_Argument.Error "Invalid JS_Object for Integer.")
|
||||
|
||||
## PRIVATE
|
||||
Converts the given value to a JSON serializable object.
|
||||
Decimal.to_js_object : JS_Object
|
||||
Decimal.to_js_object self =
|
||||
JS_Object.from_pairs [["type", "Decimal"], ["value", self.to_text], ["scale", self.scale], ["precision", self.precision]]
|
||||
|
||||
## PRIVATE
|
||||
Converts a JS_Object to a Decimal.
|
||||
Decimal.from (that:JS_Object) =
|
||||
case that.get "type" == "Decimal" && ["value", "scale", "precision"].all that.contains_key of
|
||||
True ->
|
||||
math_context = Math_Context.new (that.at "precision")
|
||||
raw_value = Decimal.from_string (that.at "value") math_context
|
||||
raw_value.with_scale (that.at "scale")
|
||||
False -> Error.throw (Illegal_Argument.Error "Invalid JS_Object for Decimal.")
|
||||
|
||||
## PRIVATE
|
||||
Converts the given value to a JSON serializable object.
|
||||
For Nothing, booleans, numbers and strings, this is the value itself.
|
||||
|
@ -153,6 +153,18 @@ add_specs suite_builder =
|
||||
Number.positive_infinity.to_json . should_equal "null"
|
||||
Number.negative_infinity.to_json . should_equal "null"
|
||||
|
||||
group_builder.specify "should serialise large integers and parse back" <|
|
||||
large_number = 1234567890123456789012345678901234567890
|
||||
large_number.to_json . should_equal '{"type":"Integer","value":"1234567890123456789012345678901234567890"}'
|
||||
large_number.to_json . parse_json . should_equal large_number
|
||||
|
||||
group_builder.specify "should serialise decimals and parse back" <|
|
||||
decimal = Decimal.from_string "1234567890123456789012345678901234567890.1234567890123456789012345678901234567890"
|
||||
decimal.to_json . should_equal '{"type":"Decimal","value":"1234567890123456789012345678901234567890.1234567890123456789012345678901234567890","scale":40,"precision":80}'
|
||||
decimal.to_json . parse_json . should_equal decimal
|
||||
decimal.to_json . parse_json . scale . should_equal 40
|
||||
decimal.to_json . parse_json . precision . should_equal 80
|
||||
|
||||
suite_builder.group "JS_Object" group_builder->
|
||||
group_builder.specify "should be buildable from pairs" <|
|
||||
JS_Object.from_pairs [["foo", "bar"]] . to_json . should_equal '{"foo":"bar"}'
|
||||
|
Loading…
Reference in New Issue
Block a user