generateForEnum static method

Future generateForEnum(
  1. EnumElement2 element,
  2. DogsGeneratorSettings settings,
  3. SubjectGenContext<Element2> genContext,
  4. SubjectCodeContext codeContext,
)

Implementation

static Future generateForEnum(EnumElement2 element, DogsGeneratorSettings settings,
    SubjectGenContext<Element2> genContext, SubjectCodeContext codeContext) async {
  var emitter = DartEmitter();
  var converterName = "${element.displayName}Converter";

  String serialName = element.displayName;
  serialName = settings.nameCase.recase(serialName);

  var serializableValue = serializableChecker.firstAnnotationOf(element);
  if (serializableValue != null) {
    var serialNameOverride = serializableValue.getField("serialName")?.toStringValue();
    if (serialNameOverride != null) serialName = serialNameOverride;
  }

  String? fallbackFieldName;
  final fieldValueMap = Map.fromEntries(element.fields2.where((e) => e.isEnumConstant).map((e) {
    final actual = e.displayName;
    var serializedName = e.displayName;
    serializedName = settings.enumCase.recase(serializedName);

    final propertyName = propertyNameChecker.firstAnnotationOf(e);
    if (propertyName != null) {
      serializedName = propertyName.getField("name")?.toStringValue() ?? serializedName;
    }

    final enumProperty = enumPropertyChecker.firstAnnotationOf(e);
    if (enumProperty != null) {
      serializedName = enumProperty.getField("name")?.toStringValue() ?? serializedName;
      if (enumProperty.getField("fallback")?.toBoolValue() ?? false) {
        fallbackFieldName = actual;
      }
    }

    return MapEntry(actual, serializedName);
  }));

  var clazz = Class((builder) {
    builder.name = converterName;

    builder.extend = Reference(
        "$genAlias.GeneratedEnumDogConverter<${codeContext.typeName(element.thisType)}>");

    builder.constructors.add(Constructor((builder) =>
        builder..initializers.add(Code("super.structured(serialName: '$serialName')"))));

    builder.methods.add(Method((builder) => builder
      ..name = "values"
      ..type = MethodType.getter
      ..returns = Reference("List<String>")
      ..annotations.add(CodeExpression(Code("override")))
      ..lambda = true
      ..body =
          Code("[${fieldValueMap.values.map((e) => "'${sqsLiteralEscape(e)}'").join(",")}]")));

    builder.methods.add(Method((builder) => builder
      ..name = "toStr"
      ..type = MethodType.getter
      ..returns = Reference("$genAlias.EnumToString<${codeContext.typeName(element.thisType)}> ")
      ..annotations.add(CodeExpression(Code("override")))
      ..lambda = true
      ..body = Code("""
(e) => switch(e) {
${fieldValueMap.entries.map((e) => "${codeContext.typeName(element.thisType)}.${e.key} => '${sqsLiteralEscape(e.value)}',").join("\n")}
null => throw ArgumentError('Enum value cannot be null'),
}
""")));

    builder.methods.add(Method((builder) => builder
      ..name = "fromStr"
      ..type = MethodType.getter
      ..returns =
          Reference("$genAlias.EnumFromString<${codeContext.typeName(element.thisType)}> ")
      ..annotations.add(CodeExpression(Code("override")))
      ..lambda = true
      ..body = Code("""
(e) => switch(e) {
${fieldValueMap.entries.map((e) => "'${sqsLiteralEscape(e.value)}' => ${codeContext.typeName(element.thisType)}.${e.key},").join("\n")}
_ => ${switch (fallbackFieldName) {
        null => "null",
        _ => "${codeContext.typeName(element.thisType)}.$fallbackFieldName"
      }}
}
""")));
  });
  codeContext.codeBuffer.writeln(clazz.accept(emitter));
}