diff --git a/spec/std/json/mapping_spec.cr b/spec/std/json/mapping_spec.cr index bd61ba165de7..59d5bab2a15e 100644 --- a/spec/std/json/mapping_spec.cr +++ b/spec/std/json/mapping_spec.cr @@ -1,5 +1,6 @@ require "spec" require "json" +require "big/json" private class JSONPerson JSON.mapping({ @@ -31,6 +32,10 @@ private class JSONWithBool JSON.mapping value: Bool end +private class JSONWithBigDecimal + JSON.mapping value: BigDecimal +end + private class JSONWithTime JSON.mapping({ value: {type: Time, converter: Time::Format.new("%F %T")}, @@ -518,4 +523,26 @@ describe "JSON mapping" do typeof(json.@bar).should eq(Bool) end end + + describe "BigDecimal" do + it "parses json string with BigDecimal" do + json = JSONWithBigDecimal.from_json(%({"value": "10.05"})) + json.value.should eq(BigDecimal.new("10.05")) + end + + it "parses large json ints with BigDecimal" do + json = JSONWithBigDecimal.from_json(%({"value": 9223372036854775808})) + json.value.should eq(BigDecimal.new("9223372036854775808")) + end + + it "parses json float with BigDecimal" do + json = JSONWithBigDecimal.from_json(%({"value": 10.05})) + json.value.should eq(BigDecimal.new("10.05")) + end + + it "parses large precision json floats with BigDecimal" do + json = JSONWithBigDecimal.from_json(%({"value": 0.00045808999999999997})) + json.value.should eq(BigDecimal.new("0.00045808999999999997")) + end + end end diff --git a/spec/std/json/serialization_spec.cr b/spec/std/json/serialization_spec.cr index ac7a25a709d8..6c5be193775d 100644 --- a/spec/std/json/serialization_spec.cr +++ b/spec/std/json/serialization_spec.cr @@ -91,6 +91,18 @@ describe "JSON serialization" do big.should eq(BigFloat.new("1234")) end + it "does for BigDecimal from int" do + big = BigDecimal.from_json("1234") + big.should be_a(BigDecimal) + big.should eq(BigDecimal.new("1234")) + end + + it "does for BigDecimal from int" do + big = BigDecimal.from_json("1234.05") + big.should be_a(BigDecimal) + big.should eq(BigDecimal.new("1234.05")) + end + it "does for Enum with number" do JSONSpecEnum.from_json("1").should eq(JSONSpecEnum::One) diff --git a/src/big/json.cr b/src/big/json.cr index bb54a5c612b9..62ab0a0c7998 100644 --- a/src/big/json.cr +++ b/src/big/json.cr @@ -10,3 +10,17 @@ def BigFloat.new(pull : JSON::PullParser) pull.read_float BigFloat.new(pull.raw_value) end + +def BigDecimal.new(pull : JSON::PullParser) + case pull.kind + when :int + pull.read_int + value = pull.raw_value + when :float + pull.read_float + value = pull.raw_value + else + value = pull.read_string + end + BigDecimal.new(value) +end