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

Add JSON serialization to big number types #9898

Merged
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
5 changes: 5 additions & 0 deletions spec/std/json/serialization_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,11 @@ describe "JSON serialization" do
big.to_json.should eq("1234.567891011121314")
end

pending_win32 "does for BigDecimal" do
big = BigDecimal.new("1234.567891011121314")
big.to_json.should eq("1234.567891011121314")
end

it "does for UUID" do
uuid = UUID.new("ee843b26-56d8-472b-b343-0b94ed9077ff")
uuid.to_json.should eq("\"ee843b26-56d8-472b-b343-0b94ed9077ff\"")
Expand Down
5 changes: 5 additions & 0 deletions spec/std/yaml/serialization_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,11 @@ describe "YAML serialization" do
BigFloat.from_yaml(big.to_yaml).should eq(big)
end

pending_win32 "does for BigDecimal" do
big = BigDecimal.new("1234.567891011121314")
BigDecimal.from_yaml(big.to_yaml).should eq(big)
end

it "does for Enum" do
YAMLSpecEnum.from_yaml(YAMLSpecEnum::One.to_yaml).should eq(YAMLSpecEnum::One)
end
Expand Down
124 changes: 92 additions & 32 deletions src/big/json.cr
Original file line number Diff line number Diff line change
@@ -1,44 +1,104 @@
require "json"
require "big"

def BigInt.new(pull : JSON::PullParser)
pull.read_int
BigInt.new(pull.raw_value)
end
class JSON::Builder
# Writes a big integer.
def number(number : BigInt)
scalar do
@io << number
end
end

def BigInt.from_json_object_key?(key : String)
BigInt.new(key)
rescue ArgumentError
nil
end
# Writes a big float.
def number(number : BigFloat)
scalar do
@io << number
end
end

def BigFloat.new(pull : JSON::PullParser)
pull.read_float
BigFloat.new(pull.raw_value)
# Writes a big decimal.
def number(number : BigDecimal)
scalar do
@io << number
end
end
end

def BigFloat.from_json_object_key?(key : String)
BigFloat.new(key)
rescue ArgumentError
nil
struct BigInt
def self.new(pull : JSON::PullParser)
pull.read_int
new(pull.raw_value)
end

def self.from_json_object_key?(key : String)
new(key)
rescue ArgumentError
nil
end

def to_json_object_key
to_s
end

def to_json(json : JSON::Builder)
json.number(self)
end
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)
struct BigFloat
def self.new(pull : JSON::PullParser)
case pull.kind
when .int?
pull.read_int
value = pull.raw_value
else
dukenguyenxyz marked this conversation as resolved.
Show resolved Hide resolved
pull.read_float
value = pull.raw_value
end
new(value)
end

def self.from_json_object_key?(key : String)
new(key)
rescue ArgumentError
nil
end

def to_json_object_key
to_s
end

def to_json(json : JSON::Builder)
json.number(self)
end
end

def BigDecimal.from_json_object_key?(key : String)
BigDecimal.new(key)
rescue InvalidBigDecimalException
nil
struct BigDecimal
def self.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
new(value)
end

def self.from_json_object_key?(key : String)
new(key)
rescue InvalidBigDecimalException
nil
end

def to_json_object_key
to_s
end

def to_json(json : JSON::Builder)
json.number(self)
end
end