A more compatible approach could be a JSON::PullParser
implementation that traverses a JSON::Any
structure instead of parsing JSON directly.
I’m trying to to the same; I have a JSON document with two dateTimes within an outer root. If I try to create fields for both, I need to use the same interior key, which creates an error, even though the resulting property has a different name:
property start_datetime : Time
@[JSON::Field(converter: TimeToUTC, key: "dateTime", root: "end")]
property end_datetime : Time```
“start”: {
“dateTime”: “2024-05-19T10:00:00-07:00”,
“timeZone”: “America/Los_Angeles”
},
“end”: {
“dateTime”: “2024-05-19T14:00:00-07:00”,
“timeZone”: “America/Los_Angeles”
}
The problem is using root
twice I think.
module TimeToUTC
def self.from_json(pull : JSON::PullParser) : Time
time = zone = ""
pull.read_object do |key|
case key
when "dateTime" then time = pull.read_string
when "timeZone" then zone = pull.read_string
end
end
Time.parse_rfc3339(time).to_utc
end
end
class Event
include JSON::Serializable
@[JSON::Field(converter: TimeToUTC, key: "start")]
property start_datetime : Time
@[JSON::Field(converter: TimeToUTC, key: "end")]
property end_datetime : Time
end
Should do the trick. Where you only provide the key
, then can use the converter to parse the object explicitly to extract/build what you need.
I am happy someone show that issue with json, because it give me problems as well. It will be better I thin if the json implementation can handle that (complex structure)
Your code example seems incomplete, but it might be that you’re mixing up key
and root
.
key
is the name of the property in the object, which in your example could be "start"
or "end"
. root
is the nested property, which could be "dateTime"
or "timeZone"
.
Offering since this JSON structure looks familiar — if you’re working with the Google Calendar API, I’ve got you covered with this shard.
google = Google::Client.new(
client_id: ENV["GOOGLE_CLIENT_ID"],
client_secret: ENV["GOOGLE_CLIENT_SECRET"],
redirect_uri: ENV["GOOGLE_REDIRECT_URI"],
)
google
.calendar
.events
.list(calendar, oauth_access_token)