Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions spec/std/json/mapping_spec.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require "spec"
require "json"
require "big/json"

private class JSONPerson
JSON.mapping({
Expand Down Expand Up @@ -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")},
Expand Down Expand Up @@ -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
12 changes: 12 additions & 0 deletions spec/std/json/serialization_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
14 changes: 14 additions & 0 deletions src/big/json.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #5525 (comment):

def BigDecimal.new(pull : JSON::PullParser)
  value = case pull.kind
  when :int, :float
    pull.read_raw
    pull.raw_value
  else
    pull.read_string
  end
  BigDecimal.new(value)
end

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