Line data Source code
1 : import 'package:enum_assist/src/enum_field.dart'; 2 : import 'package:enum_assist/src/templates/template_core.dart'; 3 : import 'package:enum_assist/src/util/string_helpers.dart'; 4 : import 'package:enum_assist/src/util/util.dart'; 5 : 6 : /// {@template enum_assist.map_template} 7 : /// Returns the map extension template 8 : /// {@endtemplate} 9 : class JsonConverterTemplate extends TemplateCoreDetailed<_Item> { 10 : /// {@macro enum_assist.map_template} 11 0 : JsonConverterTemplate(String enumName, Iterable<EnumField> fields, 12 : {required this.isNullable}) 13 0 : : super(enumName, fields); 14 : 15 : /// sets the template to return a nullable value 16 : final bool isNullable; 17 : 18 0 : String get _possNullType => isNullable ? '?' : ''; 19 0 : String get _possNullName => isNullable ? 'Nullable' : ''; 20 0 : String get _className => 21 0 : '${isNullable ? '_' : ''}$enumName${_possNullName}Conv'; 22 0 : String get _enumType => '$enumName$_possNullType'; 23 0 : String get _stringType => 'String$_possNullType'; 24 : 25 0 : String get _templateName => 26 0 : isNullable ? _templateNameNullable : _templateNameNonNullable; 27 0 : String get _templateNameNullable => '${_templateNameNonNullable}_nullable'; 28 0 : String get _templateNameNonNullable => 29 0 : '${enumName.toSnakeCase()}.json_converter'; 30 0 : String get _annotation => 31 0 : isNullable ? '@${enumName}Conv.nullable' : '@$_className()'; 32 : 33 0 : @override 34 : StringBuffer writeTemplate(StringBuffer buffer) { 35 : buffer 36 0 : ..writeln(''' 37 0 : /// {@template $_templateName} 38 0 : /// Serializes [$_enumType] to and from json 39 : /// 40 : /// Can be used as annotation for `json_serializable` classes 41 : /// 42 : /// ```dart 43 0 : /// $_annotation 44 0 : /// final $_enumType myEnum; 45 : /// ``` 46 0 : /// {@endtemplate}''') 47 0 : ..writeobj( 48 0 : 'class $_className extends JsonConverter<$_enumType, $_stringType>', // ignore: 49 0 : body: (classBuff, classTab) { 50 0 : classBuff.writelnTab( 51 0 : '/// {@macro ${enumName.toSnakeCase()}.json_converter}', 52 : classTab); 53 : 54 0 : if (!isNullable) { 55 : classBuff 56 0 : ..writelnTab('const $_className({this.defaultValue});', classTab) 57 0 : ..writeln() 58 0 : ..writelnTab( 59 : '/// the value to be used when no match is found', classTab) 60 0 : ..writelnTab('final $enumName? defaultValue;', classTab) 61 0 : ..writeln() 62 0 : ..writelnTab('/// {@macro $_templateNameNullable}', classTab) 63 0 : ..writelnTab( 64 0 : 'static const nullable = _${enumName}NullableConv();') 65 0 : ..writeln() 66 0 : ..writeln(map((i) => tab(i.privateFieldGetter, classTab))); 67 : } else { 68 0 : classBuff.writelnTab('const $_className();'); 69 : } 70 : 71 : classBuff 72 0 : ..writeln() 73 0 : ..writelnTab('@override', classTab) 74 0 : ..writeobj( 75 0 : '$_enumType fromJson($_stringType json)', 76 : tab: classTab, 77 0 : body: (fromBuff, fromTab) { 78 0 : fromBuff.writeobj( 79 : 'switch (json)', 80 : tab: fromTab, 81 0 : body: (switchBuff, switchTab) { 82 0 : String fromCase(_Item i) { 83 0 : String _tab([int n = 0]) => tab('', switchTab + n); 84 : 85 0 : return i.fromCaseItem(_tab(), _tab(1)); 86 : } 87 : 88 : switchBuff 89 0 : ..writeln(map(fromCase)) 90 0 : ..writelnTab('default:', switchTab); 91 : 92 0 : if (isNullable) { 93 : switchBuff 94 0 : ..writeln() 95 0 : ..writelnTab('return null;', switchTab); 96 : } else { 97 : switchBuff 98 0 : ..writelnTab( 99 : 'if (defaultValue != null) return defaultValue!;', 100 0 : switchTab + 1) 101 0 : ..writeln() 102 0 : ..writelnTab( 103 : r"throw Exception('Unknown field: $json');", 104 0 : switchTab + 1, 105 : ); 106 : } 107 : }, 108 : ); 109 : }, 110 : ) 111 0 : ..writeln() 112 0 : ..writelnTab('@override', classTab) 113 0 : ..writeln( 114 0 : '$_stringType toJson($_enumType object) => ' 115 0 : 'object$_possNullType.serialized;', 116 : ); 117 : }, 118 : ); 119 : 120 : return buffer; 121 : } 122 : 123 0 : @override 124 0 : _Item convert(EnumField e) => _Item(enumName, e, isNullable); 125 : } 126 : 127 : class _Item extends FieldTemplate<EnumField> { 128 0 : const _Item(String enumName, EnumField field, this.isNullable) 129 0 : : super(enumName, field); 130 : 131 : final bool isNullable; 132 : 133 0 : String get privateField => field.privateName; 134 0 : String get privateFieldGetter => 135 0 : "static const $privateField = '${field.getSerializedName}';"; 136 : 137 0 : String get _className => isNullable ? '${enumName}Conv.' : ''; 138 : 139 0 : String caseString(String str) => 'case $_className$str:'; 140 : 141 0 : String get fromReturnString => 'return ${field.wholeName};'; 142 : 143 0 : String fromCaseItem(String caseTab, String returnTab) => ''' 144 0 : $caseTab${caseString(privateField)} 145 0 : $returnTab$fromReturnString'''; 146 : }