json_serializable.dart
json_serializable.dart copied to clipboard
[WIP] Automatically convert custom Maps key types
Before
Map<int, String> // works
IMap<int, String> // does not work
Custom toJson / fromJson map types can now have keys serialized to strings. This expects the to/fromJson function to be of the form String Function(Object?) and Object? Function(String).
Resolves: #396
@kevmoo
Addressed your comments.
The point of this PR is to allow custom implementations of from/toJson with generics to have key values automatically serialized to strings (such as ints, doubles, datetime, and enums). Keys were being serialized properly for built in map types, but not for custom maps such as the immutable map type I'm using from the fast_immutable_collections package. The approach I took was to reuse the key serialization logic that is used for regular maps in generic types that have String?
types instead of the regular Object?
type in the toJsonK/fromJsonK functions.
i.e.
class CustomMap<K, V> {
final Map<K, V> map;
CustomMap(this.map);
factory CustomMap.fromJson(
Map<String, dynamic> json,
K Function(String?) fromJsonK,
V Function(Object?) fromJsonV,
) =>
CustomMap(json.map<K, V>(
(key, value) => MapEntry(fromJsonK(key), fromJsonV(value))));
Map<String?, dynamic> toJson(
String? Function(K) toJsonK, Object? Function(V) toJsonV) =>
map.map((key, value) => MapEntry(toJsonK(key), toJsonV(value)));
}
@TimWhiting Would this make it possible to serialize Firebase Timestamps?
@FXschwartz This PR is for custom container types with non-string keys into a string (with the same support as built in containers)
My understanding is that Firebase Timestamps are encoded as a json object.
{
nanoseconds: 0,
seconds: 1562524200
}
Are you asking for Firebase Timestamps as keys? If so, in order to be valid json you can serialize it to a string to make it a string key. Which is related but not what this PR is for. The current implementation only handles the same things that normal maps handle as keys (e.g. enums, int, DateTime, Uri).
If you had something else / more specific in mind maybe I can help you find the right issue for it.
@TimWhiting Sorry for the delay in response! Yes, I'm talking about being able to define Firebase Timestamp as a key.
I was hoping your PR was at least a workaround to #1072 where if I'm using the Firestore ODM package, json_serializable can handle the parsing of a Firestore Timestamp.
Hopefully, that makes sense, and yes if you have any ideas that would be greatly helpful, but probably don't need to exist in this PR discussion.
I'm going to close this out. Feel free to re-open if you'd like to keep cranking...