-
Notifications
You must be signed in to change notification settings - Fork 564
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
Support MapKeySerializer::serialize_some #1030
Support MapKeySerializer::serialize_some #1030
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.
Thanks — this seems fine to me.
Deserializing Map<Option<String>, T>
is already permitted.
serde_json::from_str::<BTreeMap<Option<String>, ()>>(r#"{"...":null}"#).unwrap();
Lines 2170 to 2176 in ba29a89
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> | |
where | |
V: de::Visitor<'de>, | |
{ | |
// Map keys cannot be null. | |
visitor.visit_some(self) | |
} |
When the type is used as a key, this causes serde_json to panic, even if the value is normally fine as a key.
Serde_json does not panic in this situation. Most likely serde_json returned an error and that got turned into a panic by something else in your project.
Users may serialize a type like
HashMap<Option<String>, T>
with keys that are allSome(...)
, and then be surprised when the type fails to serialize with a key that isNone
.
This is not concerning to me. As a general principle, serde operates in terms of values, not types. Being able to serialize or deserialize one particular value of a type does not convey a guarantee that you can serialize or deserialize other values of the same Rust type. For example, on all existing serde_json versions, you can serialize Map<Option<String>, T>
already (as long as the map is empty). It is not meaningful to consider whether the "type" itself is supported by serde.
Thank you for the quick response and turnaround!
Whoops, my bad! I'm not sure why I took the shortcut from "error" to "panic" here. 😅
This makes a lot of sense. Already being able to deserialize the value, and the empty map already working anyways are great examples. |
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [serde_json](https://github.com/serde-rs/json) | dependencies | patch | `1.0.96` -> `1.0.99` | --- ### Release Notes <details> <summary>serde-rs/json (serde_json)</summary> ### [`v1.0.99`](https://github.com/serde-rs/json/releases/tag/v1.0.99) [Compare Source](serde-rs/json@v1.0.98...v1.0.99) - Support serializing serde's **option** type in a map key ([#​1030](serde-rs/json#1030), thanks [@​LPGhatguy](https://github.com/LPGhatguy)) ### [`v1.0.98`](https://github.com/serde-rs/json/releases/tag/v1.0.98) [Compare Source](serde-rs/json@v1.0.97...v1.0.98) - Update indexmap dependency used by "preserve_order" feature to version 2 ### [`v1.0.97`](https://github.com/serde-rs/json/releases/tag/v1.0.97) [Compare Source](serde-rs/json@v1.0.96...v1.0.97) - Add `io_error_kind()` method to serde_json::Error: `fn io_error_kind(&self) -> Option<std::io::ErrorKind>` ([#​1026](serde-rs/json#1026)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4xMTguMCIsInVwZGF0ZWRJblZlciI6IjM1LjE0MC4zIiwidGFyZ2V0QnJhbmNoIjoiZGV2ZWxvcCJ9--> Co-authored-by: cabr2-bot <cabr2.help@gmail.com> Co-authored-by: crapStone <crapstone01@gmail.com> Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1941 Reviewed-by: crapStone <crapstone01@gmail.com> Co-authored-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org> Co-committed-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
This PR updates
MapKeySerializer::serialize_some
to matchSerializer::serialize_some
.Currently, all calls to
serialize_some
are rejected with thekey_must_be_a_string
error that many other variants use. Because there is no distinction betweenSome(T)
andT
in JSON, I think that serializing the underlying type directly is a better behavior for this function.I think this change is useful for serializing types that have internal nullability. In a project I am working on, there is a bitpattern in a type I am serializing that I would like serialize as
null
. To behave correctly with as many serializers as I can, I useserialize_some
andserialize_none
. When the type is used as a key, this causes serde_json to panic, even if the value is normally fine as a key.One argument against this change is that it creates a new footgun. Users may serialize a type like
HashMap<Option<String>, T>
with keys that are allSome(...)
, and then be surprised when the type fails to serialize with a key that isNone
. Currently, I think that any types that are valid map keys are always valid map keys, which is desirable.I'm hoping to get feedback by opening this PR to figure out if this is the right direction... or not!