Skip to content

Commit

Permalink
#130: renamed json key to json value
Browse files Browse the repository at this point in the history
  • Loading branch information
jorre127 committed Sep 7, 2023
1 parent fe7f12a commit 5a1e7cf
Show file tree
Hide file tree
Showing 12 changed files with 70 additions and 132 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ Gender:
abbreviation: y
```

Define custom json key using is_json_key, the value of this property will then be used to parse from json
Define custom json key using is_json_value, the value of this property will then be used to parse from json

```yaml
Gender:
Expand All @@ -423,7 +423,7 @@ Gender:
properties:
key:
type: String
is_json_key: true
is_json_value: true
abbreviation: String
values:
MALE:
Expand Down Expand Up @@ -453,7 +453,7 @@ Gender:
properties:
key:
type: String
is_json_key: true
is_json_value: true
abbreviation:
type: String
default_value: m
Expand Down
6 changes: 3 additions & 3 deletions example/model_generator/enums.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Gender:
properties:
value:
type: String
is_json_key: true
is_json_value: true
values:
MALE:
properties:
Expand Down Expand Up @@ -40,7 +40,7 @@ Status:
properties:
value:
type: int
is_json_key: true
is_json_value: true
values:
status_0:
properties:
Expand All @@ -61,7 +61,7 @@ DoubleStatus:
properties:
value:
type: double
is_json_key: true
is_json_value: true
values:
status_0:
properties:
Expand Down
121 changes: 39 additions & 82 deletions lib/config/yml_generator_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,24 @@ class YmlGeneratorConfig {

List<Model> get models => _models;

YmlGeneratorConfig(
PubspecConfig pubspecConfig, String configContent, this.fileName) {
YmlGeneratorConfig(PubspecConfig pubspecConfig, String configContent, this.fileName) {
final yamlContent = loadYaml(configContent);
if (yamlContent == null) return; // Ignore empty file
yamlContent.forEach((key, value) {
final String baseDirectory =
value['base_directory'] ?? pubspecConfig.baseDirectory;
final String baseDirectory = value['base_directory'] ?? pubspecConfig.baseDirectory;
final String? path = value['path'];
final String? extendsModel = value['extends'];
final bool generateForGenerics =
value['generate_for_generics'] ?? pubspecConfig.generateForGenerics;
final bool generateForGenerics = value['generate_for_generics'] ?? pubspecConfig.generateForGenerics;

final extraImports =
value.containsKey('extra_imports') ? <String>[] : null;
final extraImports = value.containsKey('extra_imports') ? <String>[] : null;
final extraImportsVal = value['extra_imports'];
extraImportsVal?.forEach((e) {
if (e != null) {
extraImports!.add(e.toString());
}
});

final extraAnnotations =
value.containsKey('extra_annotations') ? <String>[] : null;
final extraAnnotations = value.containsKey('extra_annotations') ? <String>[] : null;
final extraAnnotationsVal = value['extra_annotations'];
extraAnnotationsVal?.forEach((e) {
if (e != null) {
Expand Down Expand Up @@ -93,35 +88,30 @@ class YmlGeneratorConfig {
throw Exception('Properties can not be null. model: $key');
}
if (properties is! YamlMap?) {
throw Exception(
'Properties should be a map, right now you are using a ${properties.runtimeType}. model: $key');
throw Exception('Properties should be a map, right now you are using a ${properties.runtimeType}. model: $key');
}
if (type == 'enum') {
final deprecatedItemType = value['item_type'];
if (deprecatedItemType != null) {
throw Exception(
'item_type is removed, follow the migration to version 7.0.0');
throw Exception('item_type is removed, follow the migration to version 7.0.0');
}

final deprecatedGenerateExtensions = value['generate_extensions'];
if (deprecatedGenerateExtensions != null) {
throw Exception(
'generate_extensions is removed, follow the migration to version 7.0.0');
throw Exception('generate_extensions is removed, follow the migration to version 7.0.0');
}

final deprecatedGenerateMap = value['generate_map'];
if (deprecatedGenerateMap != null) {
throw Exception(
'generate_map is removed, follow the migration to version 7.0.0');
throw Exception('generate_map is removed, follow the migration to version 7.0.0');
}

final uppercaseEnums =
(value['uppercase_enums'] ?? pubspecConfig.uppercaseEnums) == true;
final uppercaseEnums = (value['uppercase_enums'] ?? pubspecConfig.uppercaseEnums) == true;

final fields = <EnumField>[];
final enumProperties = <EnumProperty>[];
properties?.forEach((propertyKey, propertyValue) {
final bool isJsonKey;
final bool isJsonvalue;
final String type;
final String? defaultValue;
final ItemType itemType;
Expand All @@ -130,32 +120,27 @@ class YmlGeneratorConfig {

if (propertyValue is YamlMap) {
type = propertyValue['type'];
isJsonKey = propertyValue['is_json_key'] == true;
isJsonvalue = propertyValue['is_json_value'] == true;
defaultValue = propertyValue['default_value']?.toString();
} else {
type = propertyValue;
isJsonKey = false;
isJsonvalue = false;
defaultValue = null;
}

final optional = type.endsWith('?');
final typeString =
optional ? type.substring(0, type.length - 1) : type;
final typeString = optional ? type.substring(0, type.length - 1) : type;

itemType = _parseSimpleType(typeString);

if (itemType is! StringType &&
itemType is! DoubleType &&
itemType is! IntegerType &&
itemType is! BooleanType) {
throw Exception(
'$propertyKey should have a type of integer, boolean, double or string');
if (itemType is! StringType && itemType is! DoubleType && itemType is! IntegerType && itemType is! BooleanType) {
throw Exception('$propertyKey should have a type of integer, boolean, double or string');
}

enumProperties.add(EnumProperty(
name: name,
type: itemType,
isJsonKey: isJsonKey,
isJsonvalue: isJsonvalue,
isOptional: optional,
defaultValue: defaultValue,
));
Expand Down Expand Up @@ -208,23 +193,18 @@ class YmlGeneratorConfig {
models.add(enumModel);
} else {
final staticCreate = (value['static_create'] ?? false) == true;
final disallowNullForDefaults =
value.containsKey('disallow_null_for_defaults')
? (value['disallow_null_for_defaults'] == true)
: pubspecConfig.disallowNullForDefaults;
final disallowNullForDefaults = value.containsKey('disallow_null_for_defaults') ? (value['disallow_null_for_defaults'] == true) : pubspecConfig.disallowNullForDefaults;
final fields = <Field>[];
properties?.forEach((propertyKey, propertyValue) {
if (propertyValue is YamlMap) {
fields.add(getField(propertyKey, propertyValue,
disallowNullForDefaults: disallowNullForDefaults));
fields.add(getField(propertyKey, propertyValue, disallowNullForDefaults: disallowNullForDefaults));
} else if (propertyValue is String) {
fields.add(getSimpleField(name: propertyKey, value: propertyValue));
} else {
throw Exception('$propertyKey should be an object');
}
});
final mappedConverters =
converters?.map((element) => element.toString()).toList();
final mappedConverters = converters?.map((element) => element.toString()).toList();
models.add(ObjectModel(
name: key,
path: path,
Expand All @@ -246,36 +226,25 @@ class YmlGeneratorConfig {
});
}

Field getField(String name, YamlMap property,
{required bool disallowNullForDefaults}) {
Field getField(String name, YamlMap property, {required bool disallowNullForDefaults}) {
try {
if (property.containsKey('required')) {
throw ArgumentError(
'required is removed, follow the migration to version 7.0.0');
throw ArgumentError('required is removed, follow the migration to version 7.0.0');
}
final ignored =
property.containsKey('ignore') && property['ignore'] == true;
final includeFromJson = !property.containsKey('includeFromJson') ||
property['includeFromJson'] == true;
final includeToJson = !property.containsKey('includeToJson') ||
property['includeToJson'] == true;
final nonFinal = ignored ||
property.containsKey('non_final') && property['non_final'] == true;
final includeIfNull = property.containsKey('include_if_null') &&
property['include_if_null'] == true;
final ignored = property.containsKey('ignore') && property['ignore'] == true;
final includeFromJson = !property.containsKey('includeFromJson') || property['includeFromJson'] == true;
final includeToJson = !property.containsKey('includeToJson') || property['includeToJson'] == true;
final nonFinal = ignored || property.containsKey('non_final') && property['non_final'] == true;
final includeIfNull = property.containsKey('include_if_null') && property['include_if_null'] == true;
final unknownEnumValue = property['unknown_enum_value'];
final jsonKey = property['jsonKey'] ?? property['jsonkey'];
final fromJson = property['fromJson'];
final toJson = property['toJson'];
final description = property.containsKey('description')
? property['description']!.toString()
: null;
final description = property.containsKey('description') ? property['description']!.toString() : null;
final type = property['type'] as String?;
final skipEquality = property['ignore_equality'] == true;
final defaultValue = property['default_value']?.toString();
final disallowNull = property.containsKey('disallow_null')
? (property['disallow_null'] == true)
: disallowNullForDefaults;
final disallowNull = property.containsKey('disallow_null') ? (property['disallow_null'] == true) : disallowNullForDefaults;
ItemType itemType;

if (type == null) {
Expand Down Expand Up @@ -341,9 +310,7 @@ class YmlGeneratorConfig {
return 'DateTime';
} else if (lowerType == 'int' || lowerType == 'integer') {
return 'int';
} else if (lowerType == 'object' ||
lowerType == 'dynamic' ||
lowerType == 'any') {
} else if (lowerType == 'object' || lowerType == 'dynamic' || lowerType == 'any') {
return 'dynamic';
} else {
return typeName;
Expand All @@ -358,17 +325,15 @@ class YmlGeneratorConfig {
//Maybe a generic
final dartType = DartType(name);
if (dartType.generics.isEmpty) {
throw Exception(
'getPathForName is null: because `$name` was not added to the config file');
throw Exception('getPathForName is null: because `$name` was not added to the config file');
}
final paths = <String>{};
for (final element in dartType.generics) {
paths.addAll(getPathsForName(pubspecConfig, element.toString()));
}
return paths;
} else {
final baseDirectory =
foundModel.baseDirectory ?? pubspecConfig.baseDirectory;
final baseDirectory = foundModel.baseDirectory ?? pubspecConfig.baseDirectory;
final path = foundModel.path;
if (path == null) {
return [baseDirectory];
Expand Down Expand Up @@ -422,26 +387,22 @@ class YmlGeneratorConfig {

Model? getModelByName(ItemType itemType) {
if (itemType is! ObjectType) return null;
final model =
models.firstWhereOrNull((model) => model.name == itemType.name);
final model = models.firstWhereOrNull((model) => model.name == itemType.name);
if (model == null) {
throw Exception(
'getModelByName is null: because `${itemType.name}` was not added to the config file');
throw Exception('getModelByName is null: because `${itemType.name}` was not added to the config file');
}
return model;
}

void checkTypesKnown(final Set<String> names, String type) {
if (!TypeChecker.isKnownDartType(type) && !names.contains(type)) {
throw Exception(
'Could not generate all models. `$type` is not added to the config file, but is extended. These types are known: ${names.join(',')}');
throw Exception('Could not generate all models. `$type` is not added to the config file, but is extended. These types are known: ${names.join(',')}');
}
}

ItemType _parseSimpleType(String type) {
final listRegex = RegExp(r'^\s*[Ll]ist<\s*([a-zA-Z_0-9<>]*)\s*>\s*$');
final mapRegex =
RegExp(r'^\s*[Mm]ap<([a-zA-Z_0-9<>]*)\s*,\s*([a-zA-Z_0-9<>]*)\s*>\s*$');
final mapRegex = RegExp(r'^\s*[Mm]ap<([a-zA-Z_0-9<>]*)\s*,\s*([a-zA-Z_0-9<>]*)\s*>\s*$');

final lowerType = type.toLowerCase();

Expand All @@ -462,21 +423,17 @@ class YmlGeneratorConfig {
return ArrayType(_makeGenericName(arrayType));
} else if (mapRegex.hasMatch(type)) {
final match = mapRegex.firstMatch(type)!;
return MapType(
key: _makeGenericName(match.group(1)!),
valueName: _makeGenericName(match.group(2)!));
return MapType(key: _makeGenericName(match.group(1)!), valueName: _makeGenericName(match.group(2)!));
}
return ObjectType(type);
}

YmlGeneratorConfig.merge(Iterable<YmlGeneratorConfig> configs, String dirName)
: fileName = dirName {
YmlGeneratorConfig.merge(Iterable<YmlGeneratorConfig> configs, String dirName) : fileName = dirName {
final names = <String, YmlGeneratorConfig>{};
for (final config in configs) {
for (final model in config.models) {
if (names.containsKey(model.name)) {
throw Exception(
'Model with same name ${model.name} found in multiple files: ${names[model.name]!.fileName} and ${config.fileName}');
throw Exception('Model with same name ${model.name} found in multiple files: ${names[model.name]!.fileName} and ${config.fileName}');
}
names[model.name] = config;
}
Expand Down
12 changes: 4 additions & 8 deletions lib/model/model/enum_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,8 @@ class EnumModel extends Model {
String? validate() {
for (final property in properties) {
for (final field in fields) {
final value = field.values
.firstWhereOrNull((value) => value.propertyName == property.name)
?.value;
if (value == null &&
!property.isOptional &&
property.defaultValue == null) {
final value = field.values.firstWhereOrNull((value) => value.propertyName == property.name)?.value;
if (value == null && !property.isOptional && property.defaultValue == null) {
return 'There is no value defined for property ${property.name} for the enum value ${field.name} in model $name. Either make this property optional or give it a value';
}
final toParseValue = value ?? property.defaultValue;
Expand Down Expand Up @@ -117,7 +113,7 @@ class EnumField {
}

class EnumProperty {
final bool isJsonKey;
final bool isJsonvalue;
final bool isOptional;
final String name;
String? defaultValue;
Expand All @@ -128,7 +124,7 @@ class EnumProperty {
required this.type,
required this.isOptional,
this.defaultValue,
this.isJsonKey = false,
this.isJsonvalue = false,
});
}

Expand Down
15 changes: 4 additions & 11 deletions lib/writer/enum_model_writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,15 @@ class EnumModelWriter {

final jsonModelName = CaseUtil(jsonModel.name);
final properties = jsonModel.properties;
final keyProperty =
properties.firstWhereOrNull((property) => property.isJsonKey);
final addDefaultJsonKey =
keyProperty == null && jsonModel.addJsonKeyToProperties;
final keyProperty = properties.firstWhereOrNull((property) => property.isJsonvalue);
final addDefaultJsonKey = keyProperty == null && jsonModel.addJsonKeyToProperties;
final addProperties = properties.isNotEmpty || addDefaultJsonKey;

sb.writeln('enum ${jsonModelName.pascalCase} {');
for (var key in jsonModel.fields) {
final jsonValue = key.values
.firstWhereOrNull(
(value) => value.propertyName == keyProperty?.name)
?.value ??
key.serializedName;
final jsonValue = key.values.firstWhereOrNull((value) => value.propertyName == keyProperty?.name)?.value ?? key.serializedName;
final propertyType = keyProperty?.type;
final isLast =
jsonModel.fields.indexOf(key) == (jsonModel.fields.length - 1);
final isLast = jsonModel.fields.indexOf(key) == (jsonModel.fields.length - 1);

if (key.description != null) {
sb.writeln(' ///${key.description}');
Expand Down
Loading

0 comments on commit 5a1e7cf

Please sign in to comment.