-
Notifications
You must be signed in to change notification settings - Fork 420
Open
Description
TL;DR: minimal reproducible bug:
class A<T> {}
A<T> fromJson<T>(String input) => A<T>();
String toJson<T>(A<T> input) => '$input';
@JsonSerializable()
class Serializable<T> {
const Serializable({required this.a});
@JsonKey(fromJson: fromJson, toJson: toJson)
final A<T> a;
}
The above breaks the builder.
In an attempt to work around #1507, I end up with the following:
sealed class Slug<T> {}
class Asd extends Slug<String> {}
class Lol extends Slug<int> {}
class Rofl extends Slug<double> {}
class Lmao extends Slug<(int, int)> {}
@JsonSerializable()
class Serializable<T> {
const Serializable(this.slug);
final Slug<T> slug;
}
The above outputs:
[SEVERE] json_serializable on lib/src/features/models/lol_dto.dart:
Could not generate `fromJson` code for `slug`.
To support the type `Slug` you can:
* Use `JsonConverter`
https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html
* Use `JsonKey` fields `fromJson` and `toJson`
https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html
https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html
package:asdlol/src/features/models/lol_dto.dart:19:17
╷
19 │ final Slug<T> slug;
│ ^^^^
╵
But that's expected.
So, I follow the first advice, the JsonConverter
way.
@JsonSerializable()
class Serializable<T> {
const Serializable(this.slug);
@SlugConverter<T>() // this has been added
final Slug<T> slug;
}
class SlugConverter<T> extends JsonConverter<Slug<T>, String> {
const SlugConverter();
@override
String toJson(Slug<T> object) {
return object.runtimeType.toString();
}
@override
Slug<T> fromJson(String json) {
switch (json) {
case 'Asd':
return Asd() as Slug<T>;
case 'Lol':
return Lol() as Slug<T>;
case 'Rofl':
return Rofl() as Slug<T>;
case 'Lmao':
return Lmao() as Slug<T>;
default:
throw Exception('Unknown slug type: $json');
}
}
}
But the above is straight ignored by the builder, which outputs exactly the same message.
Am I doing something wrong? If so, can I be welcomed with a more informative message? 😸
Then, I try the JsonKey
way.
@JsonSerializable()
class Serializable<T> {
const Serializable(this.slug);
@JsonKey(fromJson: slugFromJson, toJson: slugToJson) // let's try this one now
final Slug<T> slug;
}
String slugToJson<T>(Slug<T> object) {
return object.runtimeType.toString();
}
Slug<T> slugFromJson<T>(String json) {
switch (json) {
case 'Asd':
return Asd() as Slug<T>;
case 'Lol':
return Lol() as Slug<T>;
case 'Rofl':
return Rofl() as Slug<T>;
case 'Lmao':
return Lmao() as Slug<T>;
default:
throw Exception('Unknown slug type: $json');
}
}
But the above leads the builder to output:
[SEVERE] json_serializable on lib/src/features/models/lol_dto.dart:
Error with `@JsonKey` on the `slug` field. The `toJson` function `slugToJson` argument type `Slug<T>` is not compatible with field type `Slug<T>`.
package:asdlol/src/features/models/lol_dto.dart:19:17
╷
19 │ final Slug<T> slug;
│ ^^^^
╵
Say again? Slug<T>
is not compatible with Slug<T>
? 😵💫
I'm unsure what I can actually do at this point.
ArturoRomanelli and matbud
Metadata
Metadata
Assignees
Labels
No labels