-
-
Notifications
You must be signed in to change notification settings - Fork 191
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
Fix optionally_at
to handle Nil mid-path
#809
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello! Doesn't this patch change the behaviour of all indexing, not just optional indexing?
Oh, index wasn't where I intended to make the change. Will take another look later. |
Signed-off-by: James Hillyerd <[email protected]>
Signed-off-by: James Hillyerd <[email protected]>
76769d1
to
5cc7520
Compare
Signed-off-by: James Hillyerd <[email protected]>
After looking at it, it seemed like adding a second "optional" In 08cabcc I also flipped the is_null check to happen before calling bare_index, as is_null looks cheaper to call. I haven't benchmarked the change, and am happy to revert it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, thank you!
It looks like you've removed the need for the handle_miss
parameter from index
and it's not used in optional_index
, so it could be removed in both.
Could you update the changelog and update the optionally_at
documentation to detail the behaviour also please 🙏
Signed-off-by: James Hillyerd <[email protected]>
Signed-off-by: James Hillyerd <[email protected]>
Let me know if you think including the use of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I'm struggling to come to a firm conclusion as to whether this API is right.
The change here is to go from being able to decode optional fields, to being able to decode optional and also nullable fields, however it doesn't handle the final value for you. This seems to mix two related things (which could be convenient, but removes some control from the programmer), and there's an inconsistency with how null values are handled depending on where they are in the path.
How would someone write a decoder where it is optional only?
Do we need a different name?
How do we resolve the difference between the nulls at different places on the path?
Could you share you use concrete case for this decoder please, that'll help me understand the requirements.
Sorry I'm being difficult here, but it's very important to get this right!
You are right that we would be removing some control from the programmer in terms of handling a nil-dict-value differently from a missing-dict-value. My initial assumption was this was not an important distinction for decoding JSON, but given that decoders aren't specific to JSON, that's probably a bad assumption. Giving it a new name would be nice, and that is what I originally proposed in #4202. Personally I'd prefer it use the |
My use case is parsing nested JSON messages from Home Assistant, which does not have a spec for me to follow. What tripped me up in the message below was trying to extract {
"id": 1,
"type": "event",
"event": {
"variables": {
"trigger": {
"id": "0",
"idx": "0",
"alias ": null,
"platform": "state",
"entity_id": "binary_sensor.presence_sensor_occupancy",
"from_state": null,
"to_state": {
"entity_id": "binary_sensor.presence_sensor_occupancy",
"state ": "unavailable",
"attributes": {
"device_class": "occupancy",
"friendly_name": "Office Presence Sensor Occupancy"
},
"last_changed": "2025-01-13T03:01:42.730040+00:00",
"last_reported": "2025-01-13T03:01:42. 730040+00:00",
"last_updated": "2025-01-13T03:01:42.730040+00:00",
"context": {
"id": "01JHESRA6A8V3TMDZ HN29D3X5D",
"parent_id": null,
"user_id": null
}
},
"for": null,
"attribute": null,
"description": "state of binary_sensor.presence_sensor_occupancy"
}
},
"context": {
"id": "01JHESRA6A8V3TMDZHN29D3X5D ",
"parent_id": null,
"user_id": null
}
}
} Basically, I'd like to follow the robustness principle: "be conservative in what you do, be liberal in what you accept from others". If Home Assistant decides to make |
I spent some time this weekend seeing if I could implement this as a stand-alone library, but with I'm thinking I will cherrypick the Alternately, perhaps there could be a |
This is a fix for the decoding error mentioned in gleam-lang/gleam#4202 (reply in thread)
It modifies
optionally_at
to treat a mid-path Nil as a missing value, instead of a decode error. This PR does not change the behavior of Nil being present at the target of the path.Example problem, given a decoder containing:
And the following 3 JSON inputs:
The first two will decode to None as expected, but the third case will fail: