Use backed enums in php-nextgen (#16556)

This commit is contained in:
Julian Vennen 2023-09-11 14:06:50 +02:00 committed by GitHub
parent 1901bf23ea
commit 8b15d4820e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 73 additions and 151 deletions

View File

@ -20,11 +20,14 @@ package org.openapitools.codegen.languages;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption; import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConstants; import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenType; import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.SupportingFile; import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.meta.GeneratorMetadata; import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability; import org.openapitools.codegen.meta.Stability;
import org.openapitools.codegen.meta.features.*; import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -33,6 +36,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Map;
public class PhpNextgenClientCodegen extends AbstractPhpCodegen { public class PhpNextgenClientCodegen extends AbstractPhpCodegen {
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
@ -122,4 +126,32 @@ public class PhpNextgenClientCodegen extends AbstractPhpCodegen {
supportingFiles.add(new SupportingFile(".phplint.mustache", "", ".phplint.yml")); supportingFiles.add(new SupportingFile(".phplint.mustache", "", ".phplint.yml"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh")); supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
} }
@Override
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
final Map<String, ModelsMap> processed = super.postProcessAllModels(objs);
for (Map.Entry<String, ModelsMap> entry : processed.entrySet()) {
entry.setValue(postProcessModelsMap(entry.getValue()));
}
return processed;
}
private ModelsMap postProcessModelsMap(ModelsMap objs) {
for (ModelMap m : objs.getModels()) {
CodegenModel model = m.getModel();
if (model.isEnum) {
for (Map<String, Object> enumVars : (List<Map<String, Object>>) model.getAllowableValues().get("enumVars")) {
if ((Boolean) enumVars.get("isString")) {
model.vendorExtensions.putIfAbsent("x-php-enum-type", "string");
} else {
model.vendorExtensions.putIfAbsent("x-php-enum-type", "int");
}
}
}
}
return objs;
}
} }

View File

@ -79,12 +79,10 @@ class ObjectSerializer
$getter = $data::getters()[$property]; $getter = $data::getters()[$property];
$value = $data->$getter(); $value = $data->$getter();
if ($value !== null && !in_array($openAPIType, [{{&primitives}}], true)) { if ($value !== null && !in_array($openAPIType, [{{&primitives}}], true)) {
$callable = [$openAPIType, 'getAllowableEnumValues']; if ($openAPIType instanceof \BackedEnum) {
if (is_callable($callable)) { $data = $openAPIType::tryFrom($data);
/** array $callable */ if ($data === null) {
$allowedEnumTypes = $callable(); $imploded = implode("', '", array_map(fn($case) => $case->value, $openAPIType::cases()));
if (!in_array($value, $allowedEnumTypes, true)) {
$imploded = implode("', '", $allowedEnumTypes);
throw new \InvalidArgumentException("Invalid value for enum '$openAPIType', must be one of: '$imploded'"); throw new \InvalidArgumentException("Invalid value for enum '$openAPIType', must be one of: '$imploded'");
} }
} }
@ -488,9 +486,10 @@ class ObjectSerializer
} }
if (method_exists($class, 'getAllowableEnumValues')) { if ($class instanceof \BackedEnum) {
if (!in_array($data, $class::getAllowableEnumValues(), true)) { $data = $class::tryFrom($data);
$imploded = implode("', '", $class::getAllowableEnumValues()); if ($data === null) {
$imploded = implode("', '", array_map(fn($case) => $case->value, $class::cases()));
throw new \InvalidArgumentException("Invalid value for enum '$class', must be one of: '$imploded'"); throw new \InvalidArgumentException("Invalid value for enum '$class', must be one of: '$imploded'");
} }
return $data; return $data;

View File

@ -1,28 +1,9 @@
class {{classname}} enum {{classname}}: {{vendorExtensions.x-php-enum-type}}
{ {
/**
* Possible values of this enum
*/
{{#allowableValues}} {{#allowableValues}}
{{#enumVars}} {{#enumVars}}
public const {{^isString}}NUMBER_{{/isString}}{{{name}}} = {{{value}}}; case {{^isString}}NUMBER_{{/isString}}{{{name}}} = {{{value}}};
{{/enumVars}} {{/enumVars}}
{{/allowableValues}} {{/allowableValues}}
/**
* Gets allowable values of the enum
* @return string[]
*/
public static function getAllowableEnumValues()
{
return [
{{#allowableValues}}
{{#enumVars}}
self::{{^isString}}NUMBER_{{/isString}}{{{name}}}{{^-last}},
{{/-last}}
{{/enumVars}}
{{/allowableValues}}
];
}
} }

View File

@ -37,29 +37,14 @@ use \OpenAPI\Client\ObjectSerializer;
* @author OpenAPI Generator team * @author OpenAPI Generator team
* @link https://openapi-generator.tech * @link https://openapi-generator.tech
*/ */
class EnumClass enum EnumClass: string
{ {
/** case ABC = '_abc';
* Possible values of this enum
*/
public const ABC = '_abc';
public const EFG = '-efg'; case EFG = '-efg';
public const XYZ = '(xyz)'; case XYZ = '(xyz)';
/**
* Gets allowable values of the enum
* @return string[]
*/
public static function getAllowableEnumValues()
{
return [
self::ABC,
self::EFG,
self::XYZ
];
}
} }

View File

@ -37,29 +37,14 @@ use \OpenAPI\Client\ObjectSerializer;
* @author OpenAPI Generator team * @author OpenAPI Generator team
* @link https://openapi-generator.tech * @link https://openapi-generator.tech
*/ */
class OuterEnum enum OuterEnum: string
{ {
/** case PLACED = 'placed';
* Possible values of this enum
*/
public const PLACED = 'placed';
public const APPROVED = 'approved'; case APPROVED = 'approved';
public const DELIVERED = 'delivered'; case DELIVERED = 'delivered';
/**
* Gets allowable values of the enum
* @return string[]
*/
public static function getAllowableEnumValues()
{
return [
self::PLACED,
self::APPROVED,
self::DELIVERED
];
}
} }

View File

@ -37,29 +37,14 @@ use \OpenAPI\Client\ObjectSerializer;
* @author OpenAPI Generator team * @author OpenAPI Generator team
* @link https://openapi-generator.tech * @link https://openapi-generator.tech
*/ */
class OuterEnumDefaultValue enum OuterEnumDefaultValue: string
{ {
/** case PLACED = 'placed';
* Possible values of this enum
*/
public const PLACED = 'placed';
public const APPROVED = 'approved'; case APPROVED = 'approved';
public const DELIVERED = 'delivered'; case DELIVERED = 'delivered';
/**
* Gets allowable values of the enum
* @return string[]
*/
public static function getAllowableEnumValues()
{
return [
self::PLACED,
self::APPROVED,
self::DELIVERED
];
}
} }

View File

@ -37,29 +37,14 @@ use \OpenAPI\Client\ObjectSerializer;
* @author OpenAPI Generator team * @author OpenAPI Generator team
* @link https://openapi-generator.tech * @link https://openapi-generator.tech
*/ */
class OuterEnumInteger enum OuterEnumInteger: int
{ {
/** case NUMBER_0 = 0;
* Possible values of this enum
*/
public const NUMBER_0 = 0;
public const NUMBER_1 = 1; case NUMBER_1 = 1;
public const NUMBER_2 = 2; case NUMBER_2 = 2;
/**
* Gets allowable values of the enum
* @return string[]
*/
public static function getAllowableEnumValues()
{
return [
self::NUMBER_0,
self::NUMBER_1,
self::NUMBER_2
];
}
} }

View File

@ -37,29 +37,14 @@ use \OpenAPI\Client\ObjectSerializer;
* @author OpenAPI Generator team * @author OpenAPI Generator team
* @link https://openapi-generator.tech * @link https://openapi-generator.tech
*/ */
class OuterEnumIntegerDefaultValue enum OuterEnumIntegerDefaultValue: int
{ {
/** case NUMBER_0 = 0;
* Possible values of this enum
*/
public const NUMBER_0 = 0;
public const NUMBER_1 = 1; case NUMBER_1 = 1;
public const NUMBER_2 = 2; case NUMBER_2 = 2;
/**
* Gets allowable values of the enum
* @return string[]
*/
public static function getAllowableEnumValues()
{
return [
self::NUMBER_0,
self::NUMBER_1,
self::NUMBER_2
];
}
} }

View File

@ -37,26 +37,12 @@ use \OpenAPI\Client\ObjectSerializer;
* @author OpenAPI Generator team * @author OpenAPI Generator team
* @link https://openapi-generator.tech * @link https://openapi-generator.tech
*/ */
class SingleRefType enum SingleRefType: string
{ {
/** case ADMIN = 'admin';
* Possible values of this enum
*/
public const ADMIN = 'admin';
public const USER = 'user'; case USER = 'user';
/**
* Gets allowable values of the enum
* @return string[]
*/
public static function getAllowableEnumValues()
{
return [
self::ADMIN,
self::USER
];
}
} }

View File

@ -88,12 +88,10 @@ class ObjectSerializer
$getter = $data::getters()[$property]; $getter = $data::getters()[$property];
$value = $data->$getter(); $value = $data->$getter();
if ($value !== null && !in_array($openAPIType, ['\DateTime', '\SplFileObject', 'array', 'bool', 'boolean', 'byte', 'float', 'int', 'integer', 'mixed', 'number', 'object', 'string', 'void'], true)) { if ($value !== null && !in_array($openAPIType, ['\DateTime', '\SplFileObject', 'array', 'bool', 'boolean', 'byte', 'float', 'int', 'integer', 'mixed', 'number', 'object', 'string', 'void'], true)) {
$callable = [$openAPIType, 'getAllowableEnumValues']; if ($openAPIType instanceof \BackedEnum) {
if (is_callable($callable)) { $data = $openAPIType::tryFrom($data);
/** array $callable */ if ($data === null) {
$allowedEnumTypes = $callable(); $imploded = implode("', '", array_map(fn($case) => $case->value, $openAPIType::cases()));
if (!in_array($value, $allowedEnumTypes, true)) {
$imploded = implode("', '", $allowedEnumTypes);
throw new \InvalidArgumentException("Invalid value for enum '$openAPIType', must be one of: '$imploded'"); throw new \InvalidArgumentException("Invalid value for enum '$openAPIType', must be one of: '$imploded'");
} }
} }
@ -497,9 +495,10 @@ class ObjectSerializer
} }
if (method_exists($class, 'getAllowableEnumValues')) { if ($class instanceof \BackedEnum) {
if (!in_array($data, $class::getAllowableEnumValues(), true)) { $data = $class::tryFrom($data);
$imploded = implode("', '", $class::getAllowableEnumValues()); if ($data === null) {
$imploded = implode("', '", array_map(fn($case) => $case->value, $class::cases()));
throw new \InvalidArgumentException("Invalid value for enum '$class', must be one of: '$imploded'"); throw new \InvalidArgumentException("Invalid value for enum '$class', must be one of: '$imploded'");
} }
return $data; return $data;