Repository: epam-cross-platform-lab/swagger-dart-code-generator

Issue:
[FEATURE] Handle default values for enums
**Is your feature request related to a problem? Please describe.**
In #381 we tried to implement default values for enums. The problem is that the code generated by `json_serializable` doesn't include the `enums.` prefix for the default value types, which breaks compilation. Alternatively, I tried to use the `fromJson` function that we generate to pass the default value, but then the `@JsonKey` annotation has a non-constant expression, so compilation breaks again.

**Describe the solution you'd like**
We need to fix `json_serializable` to include the import prefix `enums.` in the generated code. I have tried to do this myself but it looks like the `Element` loses its import information, so we may even need to fix the `analyzer` project to include it.

**Swagger specification link**
### Single default value
```json
{
  "openapi": "3.0.1",
  "info": {
    "title": "Some service",
    "version": "1.0"
  },
  "components": {
    "schemas": {
      "Success": {
        "title": "Success",
        "enum": [
          "one",
          "two"
        ],
        "type": "string",
        "description": "An enumeration."
      }
    },
    "responses": {
      "SpaEnumResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "properties": {
                "success": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Success"
                    }
                  ],
                  "description": "The type of client validation for this field",
                  "default": "one"
                }
              }
            }
          }
        }
      }
    }
  }
}
```

```dart
test('Enums should have default values', () {
  final map = jsonDecode(schemasWithEnumsFromAllOf) as Map<String, dynamic>;
  final result = generator.generateResponses(map, 'fileName');

  expect(
    result,
    contains(
          '@JsonKey(name: \'success\', toJson: successToJson, fromJson: successFromJson, defaultValue: enums.Success.one)',
    ),
  );
});
```

### Default values list
```json
{
  "openapi": "3.0.1",
  "info": {
    "title": "Some service",
    "version": "1.0"
  },
  "components": {
    "schemas": {
      "Success": {
        "title": "Success",
        "enum": [
          "one",
          "two"
        ],
        "type": "string",
        "description": "An enumeration."
      }
    },
    "responses": {
      "SpaEnumResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "properties": {
                "successes": {
                  "items": {
                    "$ref": "#/components/schemas/Success"
                  },
                  "description": "The type of client validation for this field",
                  "type": "array",
                  "default": ["one", "two"]
                }
              }
            }
          }
        }
      }
    }
  }
}
```

```dart
test('Enum list should have default values', () {
  final map = jsonDecode(schemasWithEnumList) as Map<String, dynamic>;
  final result = generator.generateResponses(map, 'fileName');

  expect(
    result,
    contains(
          '@JsonKey(name: \'successes\', toJson: successListToJson, fromJson: successListFromJson, defaultValue: [enums.Success.one, enums.Success.two])',
    ),
  );
});
```



Discussion: @via-guy  If you want to implement it by your own - you can modify generation of _modelFromJson methods. It will be easy and safe fix. Or just let me do this. For example:

```dart
fromJson: vODResponseProductTypeFromJson


enums.VODResponseProductType vODResponseProductTypeFromJson(
    Object? vODResponseProductType) {
  if (vODResponseProductType is String) {
    return enums.$VODResponseProductTypeMap.entries
        .firstWhere(
            (element) =>
                element.value.toLowerCase() ==
                vODResponseProductType.toLowerCase(),
            orElse: () => const MapEntry(
                enums.VODResponseProductType.swaggerGeneratedUnknown, ''))
        .key;
  }

  return //** PUT DEFAULT VALUE HERE **//;
}
`
@via-guy  I think, to achieve it, you need to modify only next method in generator

```dart
String generateEnumFromJsonToJson(
      SwaggerEnum swaggerEnum, bool enumsCaseSensitive)

```
@via-guy  but anyway you can just wait while I will handle it
> @via-guy If you want to implement it by your own - you can modify generation of _modelFromJson methods. It will be easy and safe fix. Or just let me do this. For example:

@Vovanella95 this strategy doesn't work either, because the default value isn't declared for the enum, but rather for the property that references it. So you might have 2 references to the enum that define different values. E.g.
```json
{
  "components": {
    "schemas": {
      "Success": {
        "title": "Success",
        "enum": [
          "one",
          "two"
        ],
        "type": "string",
        "description": "An enumeration."
      }
    },
    "responses": {
      "SpaEnumResponse": {
        "description": "Success",
        "content": {
          "application/json": {
            "schema": {
              "properties": {
                "success": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Success"
                    }
                  ],
                  "default": "one"
                },
                "not_success": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Success"
                    }
                  ],
                  "default": "two"
                }
              }
            }
          }
        }
      }
    }
  }
}
```

This means that you can't define the return value in the `fromJson` function, as it'll be used by both properties.
@via-guy  we can add parameter to method, generation fromJson. This parameter will be default value. Different models will pass different default values.
You mean adding the parameter to `generateEnumFromJsonToJson`? Because that won't work, as it'll mean that we need multiple generations for the enum based on the default value.

Alternatively, we can't add a parameter to the generated function, e.g. 
```dart
enums.Success successFromJson(Object? success, [enums.Success? defaultValue]) {
```
because this function gets passed to `@JsonKey`, which expects a function with just 1 argument.
@via-guy  you can generate separate fromJson functions for each model. For example:

```dart
class TempModel {

@JsonKey(fromJson: _myModelModelTypeFromJson)
final enums.ModelType type;
}

Function _myModelModelTypeFromJson(Object data) {
 return () => modelTypeFromJson(data, 'defaultValueForThisModel';
}

//This method already generated. Just add default value here
enums.ModelTypeFromJson modelTypeFromJson(Object data, String defaultValue) {
}
```


I'm not sure but it will possible work :)
@Vovanella95 you reverted all of my PRs, not just the one with default values, which is what was broken. What happened?
@via-guy I supposed all of them was about default values. Sorry. Please revert needed one

Fix patch:
diff --git a/lib/src/code_generators/swagger_generator_base.dart b/lib/src/code_generators/swagger_generator_base.dart
index cf25d095..c66cd2d6 100644
--- a/lib/src/code_generators/swagger_generator_base.dart
+++ b/lib/src/code_generators/swagger_generator_base.dart
@@ -145,6 +145,7 @@ abstract class SwaggerGeneratorBase {
                 isInteger: kIntegerTypes.contains(
                   swaggerRequestParameter.schema?.type,
                 ),
+                defaultValue: swaggerRequestParameter.schema?.defaultValue,
               ),
             );
           }
diff --git a/lib/src/code_generators/swagger_models_generator.dart b/lib/src/code_generators/swagger_models_generator.dart
index df029d5b..dfb75b56 100644
--- a/lib/src/code_generators/swagger_models_generator.dart
+++ b/lib/src/code_generators/swagger_models_generator.dart
@@ -1,13 +1,13 @@
 import 'dart:convert';
 
 import 'package:collection/collection.dart';
+import 'package:recase/recase.dart';
 import 'package:swagger_dart_code_generator/src/code_generators/constants.dart';
 import 'package:swagger_dart_code_generator/src/code_generators/swagger_generator_base.dart';
+import 'package:swagger_dart_code_generator/src/exception_words.dart';
+import 'package:swagger_dart_code_generator/src/extensions/string_extension.dart';
 import 'package:swagger_dart_code_generator/src/models/generator_options.dart';
 import 'package:swagger_dart_code_generator/src/models/swagger_enum.dart';
-import 'package:recase/recase.dart';
-import 'package:swagger_dart_code_generator/src/extensions/string_extension.dart';
-import 'package:swagger_dart_code_generator/src/exception_words.dart';
 
 import 'constants.dart';
 
@@ -357,8 +357,14 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
       typeName = kDynamic;
     }
 
-    final unknownEnumValue = generateUnknownEnumValue(
-        allEnumNames, allEnumListNames, typeName.toString(), false);
+    final unknownEnumValue = generateEnumValue(
+      allEnumNames,
+      allEnumListNames,
+      propertyName,
+      typeName.toString(),
+      propertyEntryMap['default'],
+      false,
+    );
 
     final dateToJsonValue = generateToJsonForDate(propertyEntryMap);
 
@@ -369,29 +375,72 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
     }
 
     final jsonKeyContent =
-        "@JsonKey(name: '$propertyName'$includeIfNullString$dateToJsonValue$unknownEnumValue)\n";
-    return '\t$jsonKeyContent\tfinal $typeName ${generateFieldName(propertyName)};';
+        "@JsonKey(name: '$propertyName'$includeIfNullString$dateToJsonValue${unknownEnumValue.jsonKey})\n";
+    return '\t$jsonKeyContent\tfinal $typeName ${generateFieldName(propertyName)};${unknownEnumValue.fromJson}';
   }
 
-  String generateUnknownEnumValue(List<String> allEnumNames,
-      List<String> allEnumListNames, String typeName, bool isList) {
-    typeName = getValidatedClassName(typeName);
+  _JsonEnumValue generateEnumValue(
+    List<String> allEnumNames,
+    List<String> allEnumListNames,
+    String propertyName,
+    String typeName,
+    dynamic defaultValue,
+    bool isList,
+  ) {
+    final validatedTypeName = getValidatedClassName(typeName);
+
+    var jsonKey = '';
+    var fromJson = '';
+    if (allEnumNames.contains(validatedTypeName)) {
+      isList = isList || allEnumListNames.contains(validatedTypeName);
+
+      final enumNameCamelCase = typeName.replaceAll('enums.', '').camelCase;
+      final propertyNameCamelCase = propertyName.pascalCase;
+      final fromJsonPrefix = defaultValue == null
+          ? enumNameCamelCase
+          : '$enumNameCamelCase$propertyNameCamelCase';
+      final String fromJsonSuffix;
+      final String toJsonSuffix;
+      if (isList) {
+        fromJsonSuffix = 'ListFromJson';
+        toJsonSuffix = 'ListToJson';
+      } else {
+        fromJsonSuffix = 'FromJson';
+        toJsonSuffix = 'ToJson';
+      }
+      final fromJsonFunction = '$fromJsonPrefix$fromJsonSuffix';
+      jsonKey =
+          ', toJson: $enumNameCamelCase$toJsonSuffix, fromJson: $fromJsonFunction';
+
+      if (defaultValue != null) {
+        final String returnType;
+        final String valueType;
+        final String defaultValueString;
+        if (isList && defaultValue is List) {
+          valueType = 'List';
+          returnType = 'List<$validatedTypeName>';
+          final defaultValues = defaultValue
+              .map((e) => '$validatedTypeName.${e.toString().camelCase}')
+              .join(', ');
+          defaultValueString = '[$defaultValues]';
+        } else {
+          valueType = 'Object';
+          returnType = validatedTypeName;
+          final defaultValueCamelCase = defaultValue?.toString().camelCase;
+          defaultValueString = '$validatedTypeName.$defaultValueCamelCase';
+        }
+        fromJson = '''
 
-    if (allEnumListNames.contains(typeName)) {
-      isList = true;
-    }
 
-    if (allEnumNames.contains(typeName)) {
-      if (!isList) {
-        final enumNameCamelCase = typeName.replaceAll('enums.', '').camelCase;
-        return ', toJson: ${enumNameCamelCase}ToJson, fromJson: ${enumNameCamelCase}FromJson';
-      } else {
-        final enumNameCamelCase = typeName.replaceAll('enums.', '').camelCase;
-        return ', toJson: ${enumNameCamelCase}ListToJson, fromJson: ${enumNameCamelCase}ListFromJson';
+static $returnType $fromJsonFunction($valueType? value) => $enumNameCamelCase$fromJsonSuffix(value, $defaultValueString);
+            ''';
       }
     }
 
-    return '';
+    return _JsonEnumValue(
+      jsonKey: jsonKey,
+      fromJson: fromJson,
+    );
   }
 
   String generateToJsonForDate(Map<String, dynamic> map) {
@@ -439,20 +488,26 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
       typeName += options.modelPostfix;
     }
 
-    final unknownEnumValue = generateUnknownEnumValue(
-        allEnumNames, allEnumListNames, typeName, false);
+    final unknownEnumValue = generateEnumValue(
+      allEnumNames,
+      allEnumListNames,
+      propertyName,
+      typeName,
+      propertyEntryMap['default'],
+      false,
+    );
 
     final dateToJsonValue = generateToJsonForDate(propertyEntryMap);
 
     final jsonKeyContent =
-        "@JsonKey(name: '$propertyKey'$includeIfNullString$unknownEnumValue$dateToJsonValue)\n";
+        "@JsonKey(name: '$propertyKey'$includeIfNullString${unknownEnumValue.jsonKey}$dateToJsonValue)\n";
 
     if (options.nullableModels.contains(className) ||
         !requiredProperties.contains(propertyKey)) {
       typeName = typeName.makeNullable();
     }
 
-    return '\t$jsonKeyContent\tfinal $typeName ${generateFieldName(propertyName)};';
+    return '\t$jsonKeyContent\tfinal $typeName ${generateFieldName(propertyName)};${unknownEnumValue.fromJson}';
   }
 
   String generatePropertyContentByAllOf({
@@ -482,18 +537,24 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
 
     final includeIfNullString = generateIncludeIfNullString();
 
-    final unknownEnumValue = generateUnknownEnumValue(
-        allEnumNames, allEnumListNames, typeName, false);
+    final unknownEnumValue = generateEnumValue(
+      allEnumNames,
+      allEnumListNames,
+      propertyName,
+      typeName,
+      propertyEntryMap['default'],
+      false,
+    );
 
     final jsonKeyContent =
-        "@JsonKey(name: '$propertyKey'$includeIfNullString$unknownEnumValue)\n";
+        "@JsonKey(name: '$propertyKey'$includeIfNullString${unknownEnumValue.jsonKey})\n";
 
     if (options.nullableModels.contains(className) ||
         !requiredProperties.contains(propertyKey)) {
       typeName = typeName.makeNullable();
     }
 
-    return '\t$jsonKeyContent\tfinal $typeName $propertyName;';
+    return '\t$jsonKeyContent\tfinal $typeName $propertyName;${unknownEnumValue.fromJson}';
   }
 
   String generatePropertyContentByRef(
@@ -527,8 +588,14 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
       typeName += options.modelPostfix;
     }
 
-    final unknownEnumValue = generateUnknownEnumValue(
-        allEnumNames, allEnumListNames, typeName, false);
+    final unknownEnumValue = generateEnumValue(
+      allEnumNames,
+      allEnumListNames,
+      propertyName,
+      typeName,
+      propertyEntryMap['default'],
+      false,
+    );
 
     if (allEnumListNames.contains(typeName)) {
       typeName = 'List<$typeName>';
@@ -537,14 +604,14 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
     final includeIfNullString = generateIncludeIfNullString();
 
     final jsonKeyContent =
-        "@JsonKey(name: '$propertyKey'$includeIfNullString$unknownEnumValue)\n";
+        "@JsonKey(name: '$propertyKey'$includeIfNullString${unknownEnumValue.jsonKey})\n";
 
     if (options.nullableModels.contains(className) ||
         !requiredProperties.contains(propertyKey)) {
       typeName = typeName.makeNullable();
     }
 
-    return '\t$jsonKeyContent\tfinal $typeName $propertyName;';
+    return '\t$jsonKeyContent\tfinal $typeName $propertyName;${unknownEnumValue.fromJson}';
   }
 
   String generateEnumPropertyContent(
@@ -560,9 +627,14 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
 
     allEnumNames.add(enumName);
 
-    final unknownEnumValue = generateUnknownEnumValue(
-            allEnumNames, allEnumListNames, enumName, false)
-        .substring(2);
+    final unknownEnumValue = generateEnumValue(
+      allEnumNames,
+      allEnumListNames,
+      key,
+      enumName,
+      propertyEntryMap['default'],
+      false,
+    );
 
     final includeIfNullString = generateIncludeIfNullString();
 
@@ -573,8 +645,10 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
     }
 
     return '''
-  @JsonKey($unknownEnumValue$includeIfNullString)
-  final $enumPropertyName ${generateFieldName(key)};''';
+  @JsonKey(${unknownEnumValue.jsonKey.substring(2)}$includeIfNullString)
+  final $enumPropertyName ${generateFieldName(key)};
+
+  ${unknownEnumValue.fromJson}''';
   }
 
   String _generateListPropertyTypeName({
@@ -673,18 +747,24 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
       propertyName: propertyName,
     );
 
-    final unknownEnumValue = generateUnknownEnumValue(
-        allEnumNames, allEnumListNames, typeName, true);
+    final unknownEnumValue = generateEnumValue(
+      allEnumNames,
+      allEnumListNames,
+      propertyName,
+      typeName,
+      propertyEntryMap['default'],
+      true,
+    );
 
     final includeIfNullString = generateIncludeIfNullString();
 
     String jsonKeyContent;
-    if (unknownEnumValue.isEmpty) {
+    if (unknownEnumValue.jsonKey.isEmpty) {
       jsonKeyContent =
           "@JsonKey(name: '$propertyKey'$includeIfNullString${useDefaultNullForLists ? '' : ', defaultValue: <$typeName>[]'})\n";
     } else {
       jsonKeyContent =
-          "@JsonKey(name: '$propertyKey'$includeIfNullString$unknownEnumValue)\n";
+          "@JsonKey(name: '$propertyKey'$includeIfNullString${unknownEnumValue.jsonKey})\n";
     }
 
     var listPropertyName = 'List<$typeName>';
@@ -694,7 +774,7 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
       listPropertyName = listPropertyName.makeNullable();
     }
 
-    return '$jsonKeyContent  final $listPropertyName ${generateFieldName(propertyName)};';
+    return '$jsonKeyContent  final $listPropertyName ${generateFieldName(propertyName)};${unknownEnumValue.fromJson}';
   }
 
   String generateGeneralPropertyContent(
@@ -735,12 +815,18 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
       typeName = 'enums.$typeName';
     }
 
-    final unknownEnumValue = generateUnknownEnumValue(
-        allEnumNames, allEnumListNames, typeName, false);
+    final unknownEnumValue = generateEnumValue(
+      allEnumNames,
+      allEnumListNames,
+      propertyName,
+      typeName,
+      val['default'],
+      false,
+    );
 
     final dateToJsonValue = generateToJsonForDate(val);
 
-    jsonKeyContent += unknownEnumValue;
+    jsonKeyContent += unknownEnumValue.jsonKey;
     jsonKeyContent += dateToJsonValue;
 
     if ((val['type'] == 'bool' || val['type'] == 'boolean') &&
@@ -761,7 +847,7 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
       typeName += '?';
     }
 
-    return '\t$jsonKeyContent  final $typeName $propertyName;';
+    return '\t$jsonKeyContent  final $typeName $propertyName;${unknownEnumValue.fromJson}';
   }
 
   String generatePropertyContentByType(
@@ -998,21 +1084,26 @@ abstract class SwaggerModelsGenerator extends SwaggerGeneratorBase {
 
     final toLowerCaseString = !enumsCaseSensitive ? '.toLowerCase()' : '';
     final type = swaggerEnum.isInteger ? 'int' : 'String';
-    final defaultValue = swaggerEnum.isInteger ? 0 : '\'\'';
+    final defaultTypeValue = swaggerEnum.isInteger ? 0 : '\'\'';
+    final defaultEnumValue = swaggerEnum.defaultValue?.toString() ??
+        'enums.$neededName.swaggerGeneratedUnknown';
 
     return '''
 $type? ${neededName.camelCase}ToJson(enums.$neededName? ${neededName.camelCase}) {
   return enums.\$${neededName}Map[${neededName.camelCase}];
 }
 
-enums.$neededName ${neededName.camelCase}FromJson(Object? ${neededName.camelCase}) {
+enums.$neededName ${neededName.camelCase}FromJson(
+  Object? ${neededName.camelCase},
+  [enums.$neededName? defaultValue,]
+  ) {
 
 ${swaggerEnum.isInteger ? '''
 if(${neededName.camelCase} is int)
   {
     return enums.\$${neededName}Map.entries
       .firstWhere((element) => element.value == ${neededName.camelCase},
-      orElse: () => const MapEntry(enums.$neededName.swaggerGeneratedUnknown, $defaultValue))
+      orElse: () => const MapEntry(enums.$neededName.swaggerGeneratedUnknown, $defaultTypeValue))
       .key;
   }
 ''' : '''
@@ -1020,12 +1111,12 @@ if(${neededName.camelCase} is String)
   {
  return enums.\$${neededName}Map.entries
       .firstWhere((element) => element.value$toLowerCaseString == ${neededName.camelCase}$toLowerCaseString,
-      orElse: () => const MapEntry(enums.$neededName.swaggerGeneratedUnknown, $defaultValue))
+      orElse: () => const MapEntry(enums.$neededName.swaggerGeneratedUnknown, $defaultTypeValue))
       .key;
       }
 '''}
   
-    return enums.$neededName.swaggerGeneratedUnknown;
+    return defaultValue ?? $defaultEnumValue;
 }
 
 
@@ -1043,11 +1134,12 @@ List<$type> ${neededName.camelCase}ListToJson(
 }
 
 List<enums.$neededName> ${neededName.camelCase}ListFromJson(
-    List? ${neededName.camelCase}) {
+    List? ${neededName.camelCase},
+    [List<enums.$neededName>? defaultValue,]) {
 
   if(${neededName.camelCase} == null)
   {
-    return [];
+    return defaultValue ?? [];
   }
 
   return ${neededName.camelCase}
@@ -1160,12 +1252,9 @@ $copyWithMethod
 
   String generateEqualsOverride(
       String generatedProperties, String validatedClassName) {
-    final splittedProperties = generatedProperties
-        .split(';')
-        .where((element) => element.isNotEmpty)
-        .map((e) => e.substring(e.indexOf('final ') + 6))
-        .map((e) => e.split(' ')[1])
-        .toList();
+    final splittedProperties = RegExp(
+      'final .+ (.+);',
+    ).allMatches(generatedProperties).map((e) => e.group(1)!);
 
     if (splittedProperties.isEmpty) {
       return '';
@@ -1188,18 +1277,15 @@ $copyWithMethod
 
   String generateCopyWithContent(
       String generatedProperties, String validatedClassName) {
-    final splittedProperties = generatedProperties
-        .split(';')
-        .where((element) => element.isNotEmpty)
-        .map((e) => e.substring(e.indexOf('final ') + 6))
-        .map((e) {
-      final items = e.split(' ');
-      if (!items.first.endsWith('?')) {
-        items[0] += '?';
+    final splittedProperties = RegExp(
+      'final (.+) (.+);',
+    ).allMatches(generatedProperties).map((e) {
+      var type = e.group(1)!;
+      if (!type.endsWith('?')) {
+        type += '?';
       }
-
-      return items[0] + ' ' + items[1];
-    }).toList();
+      return '$type ${e.group(2)!}';
+    });
 
     if (splittedProperties.isEmpty) {
       return '';
@@ -1217,13 +1303,12 @@ $copyWithMethod
 
   String generateGetHashContent(
       String generatedProperties, String validatedClassName) {
-    final propertiesHash = generatedProperties
-        .split(';')
-        .where((element) => element.isNotEmpty)
-        .map((e) => e.substring(e.indexOf('final ') + 6))
-        .map((e) => e.substring(e.indexOf(' ') + 1))
-        .map((e) => 'const DeepCollectionEquality().hash($e)')
-        .toList();
+    final propertiesHash = RegExp(
+      'final .+ (.+);',
+    )
+        .allMatches(generatedProperties)
+        .map((e) => e.group(1)!)
+        .map((e) => 'const DeepCollectionEquality().hash($e)');
 
     final allHashComponents =
         [...propertiesHash, 'runtimeType.hashCode'].join(' ^\n');
@@ -1453,6 +1538,7 @@ $allHashComponents;
       return SwaggerEnum(
         name: 'enums.${element.name}',
         isInteger: element.isInteger,
+        defaultValue: element.defaultValue,
       );
     }).toList();
 
@@ -1469,7 +1555,11 @@ $allHashComponents;
       final isInteger =
           kIntegerTypes.contains(map['type'] ?? map['items']?['type']) ||
               enums.firstOrNull is int;
-      outResults.add(SwaggerEnum(name: name, isInteger: isInteger));
+      outResults.add(SwaggerEnum(
+        name: name,
+        isInteger: isInteger,
+        defaultValue: map['default'] ?? map['items']?['default'],
+      ));
     }
   }
 
@@ -1517,3 +1607,13 @@ $allHashComponents;
     return result;
   }
 }
+
+class _JsonEnumValue {
+  _JsonEnumValue({
+    required this.jsonKey,
+    required this.fromJson,
+  });
+
+  final String jsonKey;
+  final String fromJson;
+}
diff --git a/lib/src/models/swagger_enum.dart b/lib/src/models/swagger_enum.dart
index 3764ae17..8830b69b 100644
--- a/lib/src/models/swagger_enum.dart
+++ b/lib/src/models/swagger_enum.dart
@@ -1,31 +1,39 @@
+import 'package:collection/collection.dart';
 import 'package:swagger_dart_code_generator/src/code_generators/constants.dart';
 
 class SwaggerEnum {
   const SwaggerEnum({
     required this.name,
     required this.isInteger,
+    required this.defaultValue,
   });
 
   SwaggerEnum.fromSchema(Map<String, dynamic> schema)
       : name = schema['name'] as String,
-        isInteger = kIntegerTypes.contains(schema['type']);
+        isInteger = kIntegerTypes.contains(schema['type']),
+        defaultValue = schema['default'];
 
   final String name;
 
   /// Enums are either int or string
   final bool isInteger;
 
+  final Object? defaultValue;
+
   @override
   bool operator ==(Object other) =>
       identical(this, other) ||
       other is SwaggerEnum &&
           runtimeType == other.runtimeType &&
           name == other.name &&
-          isInteger == other.isInteger;
+          isInteger == other.isInteger &&
+          DeepCollectionEquality().equals(defaultValue, other.defaultValue);
 
   @override
-  int get hashCode => name.hashCode ^ isInteger.hashCode;
+  int get hashCode =>
+      name.hashCode ^ isInteger.hashCode ^ defaultValue.hashCode;
 
   @override
-  String toString() => '{name: $name, isInteger: $isInteger}';
+  String toString() =>
+      'SwaggerEnum{name: $name, isInteger: $isInteger, defaultValue: $defaultValue}';
 }


Test patch:
diff --git a/test/code_examples.dart b/test/code_examples.dart
index 947e52d5..10e602b2 100644
--- a/test/code_examples.dart
+++ b/test/code_examples.dart
@@ -600,7 +600,8 @@ const String schemasWithIntegers = '''
               "enum": [
                 1, 2
               ],
-              "type": "integer"
+              "type": "integer",
+              "default": 1
             }
           }
         }
@@ -673,10 +674,59 @@ const String schemasWithEnumsFromAllOf = '''
                 "success": {
                   "allOf": [
                     {
-                      "$ref": "#/components/schemas/Success"
+                      "\$ref": "#/components/schemas/Success"
                     }
                   ],
-                  "description": "The type of client validation for this field"
+                  "default": "one"
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+''';
+
+const String schemasWithEnumsArrayRef = '''
+{
+  "openapi": "3.0.1",
+  "info": {
+    "title": "Some service",
+    "version": "1.0"
+  },
+  "components": {
+    "schemas": {
+      "Success": {
+        "title": "Success",
+        "enum": [
+          "one",
+          "two"
+        ],
+        "type": "string",
+        "description": "An enumeration."
+      }
+    },
+    "responses": {
+      "SpaEnumResponse": {
+        "description": "Success",
+        "content": {
+          "application/json": {
+            "schema": {
+              "properties": {
+                "success": {
+                  "items": {
+                    "\$ref": "#/components/schemas/Success"
+                  },
+                  "type": "array"
+                },
+                "successOther": {
+                  "items": {
+                    "\$ref": "#/components/schemas/Success"
+                  },
+                  "type": "array",
+                  "default": ["one", "two"]
                 }
               }
             }
diff --git a/test/generator_tests/models_generator_test.dart b/test/generator_tests/models_generator_test.dart
index 8d081ef3..07c3bb6b 100644
--- a/test/generator_tests/models_generator_test.dart
+++ b/test/generator_tests/models_generator_test.dart
@@ -5,6 +5,7 @@ import 'package:swagger_dart_code_generator/src/code_generators/v3/swagger_model
 import 'package:swagger_dart_code_generator/src/models/generator_options.dart';
 import 'package:swagger_dart_code_generator/src/models/swagger_enum.dart';
 import 'package:test/test.dart';
+
 import '../code_examples.dart';
 
 void main() {
@@ -794,7 +795,11 @@ void main() {
 
       expect(
         result,
-        contains(SwaggerEnum(name: 'enums.AccountType', isInteger: true)),
+        contains(SwaggerEnum(
+          name: 'enums.AccountType',
+          isInteger: true,
+          defaultValue: null,
+        )),
       );
     });
 
@@ -805,7 +810,11 @@ void main() {
       expect(
         result,
         contains(
-          SwaggerEnum(name: 'enums.SpaSchemaSuccessValues', isInteger: true),
+          SwaggerEnum(
+            name: 'enums.SpaSchemaSuccessValues',
+            isInteger: true,
+            defaultValue: 1,
+          ),
         ),
       );
     });
@@ -817,7 +826,11 @@ void main() {
       expect(
         result,
         contains(
-          SwaggerEnum(name: 'enums.SpaResponse', isInteger: true),
+          SwaggerEnum(
+            name: 'enums.SpaResponse',
+            isInteger: true,
+            defaultValue: null,
+          ),
         ),
       );
     });
@@ -833,13 +846,13 @@ void main() {
           SwaggerEnum(
             name: 'enums.SpaEnumResponseFailedValued',
             isInteger: true,
+            defaultValue: null,
           ),
         ),
       );
     });
   });
 
-
   group('Tests allOf enums', () {
     test('Class properties should get enums. prefix', () {
       final map = jsonDecode(schemasWithEnumsFromAllOf) as Map<String, dynamic>;
@@ -847,6 +860,57 @@ void main() {
 
       expect(result, contains('final enums.Success? success'));
     });
+
+    test('fromJson should have default value', () {
+      final map = jsonDecode(schemasWithEnumsFromAllOf) as Map<String, dynamic>;
+      final result = generator.generateResponses(map, 'fileName');
+
+      expect(
+        result,
+        contains(
+          '@JsonKey(name: \'success\', toJson: successToJson, fromJson: successSuccessFromJson)',
+        ),
+      );
+      expect(
+        result,
+        contains(
+          'enums.Success successSuccessFromJson(Object? value) => successFromJson(value, enums.Success.one)',
+        ),
+      );
+    });
+  });
+
+  group('Tests enums ref', () {
+    test('fromJson should use use the standard function', () {
+      final map = jsonDecode(schemasWithEnumsArrayRef) as Map<String, dynamic>;
+      final result = generator.generateResponses(map, 'fileName');
+
+      expect(
+        result,
+        contains(
+          '@JsonKey(name: \'success\', toJson: successListToJson, fromJson: successListFromJson)',
+        ),
+      );
+    });
+
+    test('fromJson should use use a custom default value function', () {
+      final map = jsonDecode(schemasWithEnumsArrayRef) as Map<String, dynamic>;
+      final result = generator.generateResponses(map, 'fileName');
+
+      expect(
+        result,
+        contains(
+          '@JsonKey(name: \'successOther\', toJson: successListToJson, fromJson: successSuccessOtherListFromJson)',
+        ),
+      );
+      expect(
+        result,
+        contains(
+          'static List<enums.Success> successSuccessOtherListFromJson(List? value) '
+          '=> successListFromJson(value, [enums.Success.one, enums.Success.two])',
+        ),
+      );
+    });
   });
 
   group('Tests for models from responses', () {