I have a case there I have a 127 bit int in a json file.
I get the following error:
Unhandled exception: Invalid Int64: "186709961001538790100634132976990" at line 94, column 19 (JSON::ParseException)
Is there some way to get json to have int128?
If you are also generating the JSON (or at least specifying its schema), then you could represent the value as a string and convert it using String#to_i128
(exactly how depends on how you’re parsing the JSON). If you don’t have any control over the JSON, I’m not sure what you can do.
I am not generating the json, so is there no way to parse a generator with i128?
Pretty sure 128 bit integer support is still a fairly new. So possible the JSON
and YAML
modules just need to be updated to support them. For now, I’d do something like what @RespiteSage suggested and deserialize it as a string and then manually cast it to an Int128
. String::RawConverter - Crystal 1.8.0-dev May be useful for this use case.
I’d also prob open an issue about it. Somewhat relates to Unhandled exception: Invalid Int64 · Issue #11490 · crystal-lang/crystal · GitHub.
1 Like
I opened up an issue, it is just that having the int as a string, could be very problematic for what my use case is, since it also deals with a lot of strings and numbers in general. And also it is a bit hard to cast a value inside of a json if you can’t parse it.
Are you using JSON.parse
or JSON::Serializable
?
If you’re using JSON::Serializable
, you can make a custom converter:
require "json"
json = %([{"value": 1},{"value": 186709961001538790100634132976990}])
class ToInt128Converter
def self.from_json(parser : JSON::PullParser) : Int128
value = parser.read_raw
value.to_i128
end
def self.to_json(value : Int128, builder : JSON::Builder) : Nil
builder.number value
end
end
class ValueHaver
include JSON::Serializable
@[JSON::Field(converter: ToInt128Converter)]
getter value : Int128
def initialize(@value)
end
end
a = Array(ValueHaver).from_json json
puts a.map &.value # => [1, 186709961001538790100634132976990]
That said, this is the first custom JSON converter I’ve written, so use this code at your own risk.
4 Likes
Oh, looks like we’re missing Int128.from_json
(for JSON::Serizalizable
) as well as 128-bit (and possibly larger) integers for JSON::Any
.
1 Like
Yeah, I changed from i64 to i128 in some places and compiled the language and that made so I could parse json.
What to note is that this could be causing a lot of bugs. One of my dependencies I use didn’t work after this change.
In lib/liquid/src/liquid/any.cr:5:5
5 | @raw = raw.to_i64
^---
Error: instance variable '@raw' of JSON::Any must be (Array(JSON::Any) | Bool | Float64 | Hash(String, JSON::Any) | Int128 | String | Nil), not Int64