@@ -109,29 +109,29 @@ final class Present<T> extends Optional<T> {
109109 String toString() => ' Optional.present($_value)' ;
110110}
111111
112- /// JSON converter for Optional<T > values.
113- ///
114- /// This converter handles serialization and deserialization of Optional values:
115- /// - Optional.absent() -> field omitted from JSON
116- /// - Optional.present(null) -> { " field" : null}
117- /// - Optional.present(value) -> { " field" : value}
118- ///
119- /// Usage with json_serializable:
120- /// ```dart
121- /// @JsonKey()
122- /// @OptionalConverter()
123- /// final Optional<String ? > field;
124- /// ```
125- class OptionalConverter<T > implements JsonConverter<Optional <T >, T?> {
112+ class _OptionalAbsentSentinel {
113+ const _OptionalAbsentSentinel();
114+ }
115+
116+ const _optionalAbsentSentinel = _OptionalAbsentSentinel();
117+
118+ /// Used with @JsonKey(readValue:) to distinguish absent keys from null values.
119+ Object? readOptionalValue(Map map, String key) {
120+ return map.containsKey(key) ? map[key] : _optionalAbsentSentinel;
121+ }
122+
123+ class OptionalConverter<T > implements JsonConverter<Optional <T >, Object?> {
126124 const OptionalConverter();
127125
128126 @override
129- Optional< T> fromJson(T? json) {
130- return json == null ? const Optional.absent() : Optional.present(json);
127+ Optional< T> fromJson(Object? json) {
128+ return json is _OptionalAbsentSentinel
129+ ? const Optional.absent()
130+ : Optional.present(json as T);
131131 }
132132
133133 @override
134- T ? toJson(Optional<T > object) {
134+ Object ? toJson(Optional<T > object) {
135135 return object.isPresent ? object.value : null;
136136 }
137137}
0 commit comments