Closed bambinoua closed 1 year ago
@kevmoo again. ThemeMode
is enum
from flutter/lib/src/material/app.dart
. I cannot modify flutter source file. I cannot annotate enum ThemeMode
with @JsonEnum
annotation.
So the question is how to force serialize framework's enums as index
not name
? Is it possible? If not is it possible to create a parameter in @JsonSerializable
to control this?
P.S. I do not want to create a separate copy MyThemeMode
instead of ThemeMode
just to make what I need if this enum
is already present. Moreover flutter contains enough other enums which can be used in apps.
Sadly you cannot serialize types from pkg:flutter – see https://github.com/google/json_serializable.dart/issues/236
@kevmoo I do not understand. I can serialize enums from flutter moreover your package do this but the generated map contains enum names (not exact code it is just to show):
final _generatedMap = {
ThemeMode.system, 'system',
ThemeMode.dark, 'dark',
ThemeMode.light, 'light',
}
I suppose it is generated using this code:
final _generatedMap = Map.fromEntries(ThemeMode.values.map((mode) => MapEntry(mode, mode.name)));
And then map's string values are used for serialization/deserialization, i.e.
{
"mode": "dark",
}
What I need is:
final _generatedMap = {
ThemeMode.system, 0,
ThemeMode.dark, 1,
ThemeMode.light, 2,
}
which allows this:
{
"mode": 0,
}
If your code can generate map with names (of course it have access to any flutter structures and _buildrunner can read any structure) then it can generate map with ids.
I think it is enough to add some parameter to @JsonSerializable
which will define how to generate enum map. And then user can decide what he needs:
Map<String,dynamic> _generatedMap;
if(useEnumIndex) {
_generatedMap = Map.fromEntries(ThemeMode.values.map((mode) => MapEntry(mode, mode.index)));
} else {
_generatedMap = Map.fromEntries(ThemeMode.values.map((mode) => MapEntry(mode, mode.name)));
}
@kevmoo so what do you think?
This is a feature request, I guess. To allow customizing the encoding of enums you don't own.
It's pretty tricky, honestly.
@kevmoo
It's pretty tricky, honestly.
Why? I don't understand.
Here it is a simple class with framework's enum:
part 'app_state.g.dart';
@JsonSerializable()
class AppState {
AppState(this.mode);
final ThemeMode mode;
}
Here it is a generated code:
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'app_state.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
AppState _$AppStateFromJson(Map<String, dynamic> json) => AppState(
$enumDecode(_$ThemeModeEnumMap, json['mode']),
);
Map<String, dynamic> _$AppStateToJson(AppState instance) => <String, dynamic>{
'mode': _$ThemeModeEnumMap[instance.mode]!,
};
const _$ThemeModeEnumMap = {
ThemeMode.system: 'system',
ThemeMode.light: 'light',
ThemeMode.dark: 'dark',
};
So you somehow know how to get the name
property of enum
(string like system
is taken from name
property, right?) So all (as for me) what is required is take index
property of enum
. Or is it difficult?
@bambinoua – it's adding all of the required configuration and testing to add the feature. We need to teach add an enum-specific annotation to the field (mode
) to "tunnel" down to enum. This package is already VERY complex, so I'm leery of adding more complexity.
I have a class with internal enum
ThemeMode
. For example:How can I force to serialize
mode
asmode.index
instead of defaultmode.name
? It is naturally I cannot annotateThemeMode
withJsonEnum
.