mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-20 21:57:08 +00:00
Support normalizing anyof/oneof enum constraints to a single enum (#21917)
* Support normalizing anyof/oneof enum constraints to a single enum * Add SIMPLIFY_ONEOF_ANYOF_ENUM to the documentation * Process referenced schemas with oneof/enum as well * Implement referenced enum merging from oneof/anyof * Implement retaining the enum description as x-enum-desriptions for oneof enum * Update samples and docs with oneOf enum normalization * update samples to fix python tests * fix test file name * fix incorrect filename --------- Co-authored-by: Pieter Bos <pieter.bos@nedap.com>
This commit is contained in:
@@ -13,3 +13,5 @@ additionalProperties:
|
|||||||
nameMappings:
|
nameMappings:
|
||||||
_type: underscore_type
|
_type: underscore_type
|
||||||
type_: type_with_underscore
|
type_: type_with_underscore
|
||||||
|
openapiNormalizer:
|
||||||
|
SIMPLIFY_ONEOF_ANYOF_ENUM: false
|
||||||
|
|||||||
@@ -13,3 +13,5 @@ nameMappings:
|
|||||||
modelNameMappings:
|
modelNameMappings:
|
||||||
# The OpenAPI spec ApiResponse conflicts with the internal ApiResponse
|
# The OpenAPI spec ApiResponse conflicts with the internal ApiResponse
|
||||||
ApiResponse: ModelApiResponse
|
ApiResponse: ModelApiResponse
|
||||||
|
openapiNormalizer:
|
||||||
|
SIMPLIFY_ONEOF_ANYOF_ENUM: false
|
||||||
|
|||||||
@@ -564,6 +564,15 @@ Example:
|
|||||||
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/simplifyAnyOfStringAndEnumString_test.yaml -o /tmp/java-okhttp/ --openapi-normalizer SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING=true
|
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/simplifyAnyOfStringAndEnumString_test.yaml -o /tmp/java-okhttp/ --openapi-normalizer SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING=true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- `SIMPLIFY_ONEOF_ANYOF_ENUM`: when set to true, oneOf/anyOf with only enum sub-schemas all containing enum values will be converted to a single enum
|
||||||
|
This is enabled by default
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/simplifyOneOfWithEnums_test.yaml -o /tmp/java-okhttp/ --openapi-normalizer SIMPLIFY_ONEOF_ANYOF_ENUM=true
|
||||||
|
```
|
||||||
|
|
||||||
- `SIMPLIFY_BOOLEAN_ENUM`: when set to `true`, convert boolean enum to just enum.
|
- `SIMPLIFY_BOOLEAN_ENUM`: when set to `true`, convert boolean enum to just enum.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|||||||
@@ -88,6 +88,9 @@ public class OpenAPINormalizer {
|
|||||||
// when set to true, boolean enum will be converted to just boolean
|
// when set to true, boolean enum will be converted to just boolean
|
||||||
final String SIMPLIFY_BOOLEAN_ENUM = "SIMPLIFY_BOOLEAN_ENUM";
|
final String SIMPLIFY_BOOLEAN_ENUM = "SIMPLIFY_BOOLEAN_ENUM";
|
||||||
|
|
||||||
|
// when set to true, oneOf/anyOf with enum sub-schemas containing single values will be converted to a single enum
|
||||||
|
final String SIMPLIFY_ONEOF_ANYOF_ENUM = "SIMPLIFY_ONEOF_ANYOF_ENUM";
|
||||||
|
|
||||||
// when set to a string value, tags in all operations will be reset to the string value provided
|
// when set to a string value, tags in all operations will be reset to the string value provided
|
||||||
final String SET_TAGS_FOR_ALL_OPERATIONS = "SET_TAGS_FOR_ALL_OPERATIONS";
|
final String SET_TAGS_FOR_ALL_OPERATIONS = "SET_TAGS_FOR_ALL_OPERATIONS";
|
||||||
String setTagsForAllOperations;
|
String setTagsForAllOperations;
|
||||||
@@ -205,11 +208,12 @@ public class OpenAPINormalizer {
|
|||||||
ruleNames.add(FILTER);
|
ruleNames.add(FILTER);
|
||||||
ruleNames.add(SET_CONTAINER_TO_NULLABLE);
|
ruleNames.add(SET_CONTAINER_TO_NULLABLE);
|
||||||
ruleNames.add(SET_PRIMITIVE_TYPES_TO_NULLABLE);
|
ruleNames.add(SET_PRIMITIVE_TYPES_TO_NULLABLE);
|
||||||
|
ruleNames.add(SIMPLIFY_ONEOF_ANYOF_ENUM);
|
||||||
|
|
||||||
// rules that are default to true
|
// rules that are default to true
|
||||||
rules.put(SIMPLIFY_ONEOF_ANYOF, true);
|
rules.put(SIMPLIFY_ONEOF_ANYOF, true);
|
||||||
rules.put(SIMPLIFY_BOOLEAN_ENUM, true);
|
rules.put(SIMPLIFY_BOOLEAN_ENUM, true);
|
||||||
|
rules.put(SIMPLIFY_ONEOF_ANYOF_ENUM, true);
|
||||||
|
|
||||||
processRules(inputRules);
|
processRules(inputRules);
|
||||||
|
|
||||||
@@ -972,6 +976,8 @@ public class OpenAPINormalizer {
|
|||||||
// Remove duplicate oneOf entries
|
// Remove duplicate oneOf entries
|
||||||
ModelUtils.deduplicateOneOfSchema(schema);
|
ModelUtils.deduplicateOneOfSchema(schema);
|
||||||
|
|
||||||
|
schema = processSimplifyOneOfEnum(schema);
|
||||||
|
|
||||||
// simplify first as the schema may no longer be a oneOf after processing the rule below
|
// simplify first as the schema may no longer be a oneOf after processing the rule below
|
||||||
schema = processSimplifyOneOf(schema);
|
schema = processSimplifyOneOf(schema);
|
||||||
|
|
||||||
@@ -1000,6 +1006,11 @@ public class OpenAPINormalizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Schema normalizeAnyOf(Schema schema, Set<Schema> visitedSchemas) {
|
protected Schema normalizeAnyOf(Schema schema, Set<Schema> visitedSchemas) {
|
||||||
|
//transform anyOf into enums if needed
|
||||||
|
schema = processSimplifyAnyOfEnum(schema);
|
||||||
|
if (schema.getAnyOf() == null) {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
for (int i = 0; i < schema.getAnyOf().size(); i++) {
|
for (int i = 0; i < schema.getAnyOf().size(); i++) {
|
||||||
// normalize anyOf sub schemas one by one
|
// normalize anyOf sub schemas one by one
|
||||||
Object item = schema.getAnyOf().get(i);
|
Object item = schema.getAnyOf().get(i);
|
||||||
@@ -1275,6 +1286,161 @@ public class OpenAPINormalizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the schema is anyOf and all sub-schemas are enums (with one or more values),
|
||||||
|
* then simplify it to a single enum schema containing all the values.
|
||||||
|
*
|
||||||
|
* @param schema Schema
|
||||||
|
* @return Schema
|
||||||
|
*/
|
||||||
|
protected Schema processSimplifyAnyOfEnum(Schema schema) {
|
||||||
|
if (!getRule(SIMPLIFY_ONEOF_ANYOF_ENUM)) {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schema.getAnyOf() == null || schema.getAnyOf().isEmpty()) {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
if(schema.getOneOf() != null && !schema.getOneOf().isEmpty() ||
|
||||||
|
schema.getAllOf() != null && !schema.getAllOf().isEmpty() ||
|
||||||
|
schema.getNot() != null) {
|
||||||
|
//only convert to enum if anyOf is the only composition
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
return simplifyComposedSchemaWithEnums(schema, schema.getAnyOf(), "anyOf");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the schema is oneOf and all sub-schemas are enums (with one or more values),
|
||||||
|
* then simplify it to a single enum schema containing all the values.
|
||||||
|
*
|
||||||
|
* @param schema Schema
|
||||||
|
* @return Schema
|
||||||
|
*/
|
||||||
|
protected Schema processSimplifyOneOfEnum(Schema schema) {
|
||||||
|
if (!getRule(SIMPLIFY_ONEOF_ANYOF_ENUM)) {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schema.getOneOf() == null || schema.getOneOf().isEmpty()) {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
if(schema.getAnyOf() != null && !schema.getAnyOf().isEmpty() ||
|
||||||
|
schema.getAllOf() != null && !schema.getAllOf().isEmpty() ||
|
||||||
|
schema.getNot() != null) {
|
||||||
|
//only convert to enum if oneOf is the only composition
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
return simplifyComposedSchemaWithEnums(schema, schema.getOneOf(), "oneOf");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simplifies a composed schema (oneOf/anyOf) where all sub-schemas are enums
|
||||||
|
* to a single enum schema containing all the values.
|
||||||
|
*
|
||||||
|
* @param schema Schema to modify
|
||||||
|
* @param subSchemas List of sub-schemas to check
|
||||||
|
* @param schemaType Type of composed schema ("oneOf" or "anyOf")
|
||||||
|
* @return Simplified schema
|
||||||
|
*/
|
||||||
|
protected Schema simplifyComposedSchemaWithEnums(Schema schema, List<Object> subSchemas, String composedType) {
|
||||||
|
Map<Object, String> enumValues = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
if(schema.getTypes() != null && schema.getTypes().size() > 1) {
|
||||||
|
// we cannot handle enums with multiple types
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(subSchemas.size() < 2) {
|
||||||
|
//do not process if there's less than 2 sub-schemas. It will be normalized later, and this prevents
|
||||||
|
//named enum schemas from being converted to inline enum schemas
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
String schemaType = ModelUtils.getType(schema);
|
||||||
|
|
||||||
|
for (Object item : subSchemas) {
|
||||||
|
if (!(item instanceof Schema)) {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
Schema subSchema = ModelUtils.getReferencedSchema(openAPI, (Schema) item);
|
||||||
|
|
||||||
|
// Check if this sub-schema has an enum (with one or more values)
|
||||||
|
if (subSchema.getEnum() == null || subSchema.getEnum().isEmpty()) {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure all sub-schemas have the same type (if type is specified)
|
||||||
|
if(subSchema.getTypes() != null && subSchema.getTypes().size() > 1) {
|
||||||
|
// we cannot handle enums with multiple types
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
String subSchemaType = ModelUtils.getType(subSchema);
|
||||||
|
if (subSchemaType != null) {
|
||||||
|
if (schemaType == null) {
|
||||||
|
schemaType = subSchemaType;
|
||||||
|
} else if (!schemaType.equals(subSchema.getType())) {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add all enum values from this sub-schema to our collection
|
||||||
|
if(subSchema.getEnum().size() == 1) {
|
||||||
|
String description = subSchema.getTitle() == null ? "" : subSchema.getTitle();
|
||||||
|
if(subSchema.getDescription() != null) {
|
||||||
|
if(!description.isEmpty()) {
|
||||||
|
description += " - ";
|
||||||
|
}
|
||||||
|
description += subSchema.getDescription();
|
||||||
|
}
|
||||||
|
enumValues.put(subSchema.getEnum().get(0), description);
|
||||||
|
} else {
|
||||||
|
for(Object e: subSchema.getEnum()) {
|
||||||
|
enumValues.put(e, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return createSimplifiedEnumSchema(schema, enumValues, schemaType, composedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a simplified enum schema from collected enum values.
|
||||||
|
*
|
||||||
|
* @param originalSchema Original schema to modify
|
||||||
|
* @param enumValues Collected enum values
|
||||||
|
* @param schemaType Consistent type across sub-schemas
|
||||||
|
* @param composedType Type of composed schema being simplified
|
||||||
|
* @return Simplified enum schema
|
||||||
|
*/
|
||||||
|
protected Schema createSimplifiedEnumSchema(Schema originalSchema, Map<Object, String> enumValues, String schemaType, String composedType) {
|
||||||
|
// Clear the composed schema type
|
||||||
|
if ("oneOf".equals(composedType)) {
|
||||||
|
originalSchema.setOneOf(null);
|
||||||
|
} else if ("anyOf".equals(composedType)) {
|
||||||
|
originalSchema.setAnyOf(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ModelUtils.getType(originalSchema) == null && schemaType != null) {
|
||||||
|
//if type was specified in subschemas, keep it in the main schema
|
||||||
|
ModelUtils.setType(originalSchema, schemaType);
|
||||||
|
}
|
||||||
|
|
||||||
|
originalSchema.setEnum(new ArrayList<>(enumValues.keySet()));
|
||||||
|
if(enumValues.values().stream().anyMatch(e -> !e.isEmpty())) {
|
||||||
|
//set x-enum-descriptions only if there's at least one non-empty description
|
||||||
|
originalSchema.addExtension("x-enum-descriptions", new ArrayList<>(enumValues.values()));
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.debug("Simplified {} with enum sub-schemas to single enum: {}", composedType, originalSchema);
|
||||||
|
|
||||||
|
return originalSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the schema is oneOf and the sub-schemas is null, set `nullable: true`
|
* If the schema is oneOf and the sub-schemas is null, set `nullable: true`
|
||||||
* instead.
|
* instead.
|
||||||
|
|||||||
@@ -2179,6 +2179,22 @@ public class ModelUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set schema type.
|
||||||
|
* For 3.1 spec, set as types, for 3.0, type
|
||||||
|
*
|
||||||
|
* @param schema the schema
|
||||||
|
* @return schema type
|
||||||
|
*/
|
||||||
|
public static void setType(Schema schema, String type) {
|
||||||
|
if (schema instanceof JsonSchema) {
|
||||||
|
schema.setTypes(null);
|
||||||
|
schema.addType(type);
|
||||||
|
} else {
|
||||||
|
schema.setType(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if any of the common attributes of the schema (e.g. readOnly, default, maximum, etc) is defined.
|
* Returns true if any of the common attributes of the schema (e.g. readOnly, default, maximum, etc) is defined.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package org.openapitools.codegen;
|
|||||||
import io.swagger.v3.oas.models.OpenAPI;
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
import io.swagger.v3.oas.models.PathItem;
|
import io.swagger.v3.oas.models.PathItem;
|
||||||
import io.swagger.v3.oas.models.media.*;
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
import io.swagger.v3.oas.models.parameters.Parameter;
|
||||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||||
import org.openapitools.codegen.utils.ModelUtils;
|
import org.openapitools.codegen.utils.ModelUtils;
|
||||||
@@ -132,6 +133,7 @@ public class OpenAPINormalizerTest {
|
|||||||
assertNull(schema.getAnyOf());
|
assertNull(schema.getAnyOf());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOpenAPINormalizerSimplifyOneOfAnyOfStringAndEnumString() {
|
public void testOpenAPINormalizerSimplifyOneOfAnyOfStringAndEnumString() {
|
||||||
// to test the rule SIMPLIFY_ONEOF_ANYOF_STRING_AND_ENUM_STRING
|
// to test the rule SIMPLIFY_ONEOF_ANYOF_STRING_AND_ENUM_STRING
|
||||||
@@ -151,6 +153,72 @@ public class OpenAPINormalizerTest {
|
|||||||
assertTrue(schema3.getEnum().size() > 0);
|
assertTrue(schema3.getEnum().size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimplifyOneOfAnyOfEnum() throws Exception {
|
||||||
|
// Load OpenAPI spec from external YAML file
|
||||||
|
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/simplifyOneOfWithEnums_test.yaml");
|
||||||
|
|
||||||
|
// Test with rule enabled (default)
|
||||||
|
Map<String, String> options = new HashMap<>();
|
||||||
|
options.put("SIMPLIFY_ONEOF_ANYOF_ENUM", "true");
|
||||||
|
OpenAPINormalizer normalizer = new OpenAPINormalizer(openAPI, options);
|
||||||
|
normalizer.normalize();
|
||||||
|
|
||||||
|
// Verify component schema was simplified
|
||||||
|
Schema colorSchema = openAPI.getComponents().getSchemas().get("ColorEnum");
|
||||||
|
assertNull(colorSchema.getOneOf());
|
||||||
|
assertEquals(colorSchema.getType(), "string");
|
||||||
|
assertEquals(colorSchema.getEnum(), Arrays.asList("red", "green", "blue", "yellow", "purple"));
|
||||||
|
|
||||||
|
Schema statusSchema = openAPI.getComponents().getSchemas().get("StatusEnum");
|
||||||
|
assertNull(statusSchema.getOneOf());
|
||||||
|
assertEquals(statusSchema.getType(), "number");
|
||||||
|
assertEquals(statusSchema.getEnum(), Arrays.asList(1, 2, 3));
|
||||||
|
|
||||||
|
// Verify parameter schema was simplified
|
||||||
|
Parameter param = openAPI.getPaths().get("/test").getGet().getParameters().get(0);
|
||||||
|
assertNull(param.getSchema().getOneOf());
|
||||||
|
assertEquals(param.getSchema().getType(), "string");
|
||||||
|
assertEquals(param.getSchema().getEnum(), Arrays.asList("option1", "option2"));
|
||||||
|
|
||||||
|
// Verify parameter schema was simplified
|
||||||
|
Parameter anyOfParam = openAPI.getPaths().get("/test").getGet().getParameters().get(1);
|
||||||
|
assertNull(anyOfParam.getSchema().getAnyOf());
|
||||||
|
assertEquals(anyOfParam.getSchema().getType(), "string");
|
||||||
|
assertEquals(anyOfParam.getSchema().getEnum(), Arrays.asList("anyof 1", "anyof 2"));
|
||||||
|
assertEquals(anyOfParam.getSchema().getExtensions().get("x-enum-descriptions"), Arrays.asList("title 1", "title 2"));
|
||||||
|
|
||||||
|
Schema combinedRefsEnum = openAPI.getComponents().getSchemas().get("combinedRefsEnum");
|
||||||
|
|
||||||
|
assertEquals(anyOfParam.getSchema().getType(), "string");
|
||||||
|
assertNull(combinedRefsEnum.get$ref());
|
||||||
|
assertEquals(combinedRefsEnum.getEnum(), Arrays.asList("A", "B", "C", "D"));
|
||||||
|
assertNull(combinedRefsEnum.getOneOf());
|
||||||
|
|
||||||
|
// Test with rule disabled
|
||||||
|
OpenAPI openAPI2 = TestUtils.parseSpec("src/test/resources/3_0/simplifyOneOfWithEnums_test.yaml");
|
||||||
|
Map<String, String> options2 = new HashMap<>();
|
||||||
|
options2.put("SIMPLIFY_ONEOF_ANYOF_ENUM", "false");
|
||||||
|
OpenAPINormalizer normalizer2 = new OpenAPINormalizer(openAPI2, options2);
|
||||||
|
normalizer2.normalize();
|
||||||
|
|
||||||
|
// oneOf will be removed, as they are in this normalizer if a primitive type has a oneOf
|
||||||
|
Schema colorSchema2 = openAPI2.getComponents().getSchemas().get("ColorEnum");
|
||||||
|
assertNull(colorSchema2.getOneOf());
|
||||||
|
assertNull(colorSchema2.getEnum());
|
||||||
|
|
||||||
|
//If you put string on every subscheme of oneOf, it does not remove it. This might need a fix at some other time
|
||||||
|
Parameter param2 = openAPI2.getPaths().get("/test").getGet().getParameters().get(0);
|
||||||
|
assertNotNull(param2.getSchema().getOneOf());
|
||||||
|
assertNull(param2.getSchema().getEnum());
|
||||||
|
|
||||||
|
//but here it does
|
||||||
|
Parameter anyOfParam2 = openAPI2.getPaths().get("/test").getGet().getParameters().get(1);
|
||||||
|
assertNull(anyOfParam2.getSchema().getOneOf());
|
||||||
|
assertNull(anyOfParam2.getSchema().getEnum());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOpenAPINormalizerSimplifyOneOfAnyOf() {
|
public void testOpenAPINormalizerSimplifyOneOfAnyOf() {
|
||||||
// to test the rule SIMPLIFY_ONEOF_ANYOF
|
// to test the rule SIMPLIFY_ONEOF_ANYOF
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
openapi: 3.0.0
|
||||||
|
info:
|
||||||
|
title: Test API
|
||||||
|
version: 1.0.0
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
ColorEnum:
|
||||||
|
type: string
|
||||||
|
oneOf:
|
||||||
|
- title: PrimaryColors
|
||||||
|
enum: ["red", "green"]
|
||||||
|
- title: SecondaryColors
|
||||||
|
enum: ["blue", "yellow"]
|
||||||
|
- title: purple
|
||||||
|
enum: ["purple"]
|
||||||
|
StatusEnum:
|
||||||
|
type: number
|
||||||
|
oneOf:
|
||||||
|
- title: active
|
||||||
|
enum: [1]
|
||||||
|
- title: inactive_pending
|
||||||
|
enum: [2, 3]
|
||||||
|
enum1:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- A
|
||||||
|
- B
|
||||||
|
enum2:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- C
|
||||||
|
- D
|
||||||
|
combinedRefsEnum:
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/enum1'
|
||||||
|
- $ref: '#/components/schemas/enum2'
|
||||||
|
paths:
|
||||||
|
/test:
|
||||||
|
get:
|
||||||
|
parameters:
|
||||||
|
- name: color
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
oneOf:
|
||||||
|
- type: string
|
||||||
|
enum: ["option1"]
|
||||||
|
- type: string
|
||||||
|
enum: ["option2"]
|
||||||
|
- name: anyOfEnum
|
||||||
|
in: query
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
anyOf:
|
||||||
|
- title: title 1
|
||||||
|
enum: [ "anyof 1" ]
|
||||||
|
- title: title 2
|
||||||
|
enum: [ "anyof 2" ]
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Success
|
||||||
@@ -8,9 +8,12 @@ servers:
|
|||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
AreaCode:
|
AreaCode:
|
||||||
oneOf:
|
enum:
|
||||||
- $ref: "#/components/schemas/StateTerritoryCode"
|
- AL
|
||||||
- $ref: "#/components/schemas/MarineAreaCode"
|
- AK
|
||||||
|
- AM
|
||||||
|
- AN
|
||||||
|
type: string
|
||||||
StateTerritoryCode:
|
StateTerritoryCode:
|
||||||
enum:
|
enum:
|
||||||
- AL
|
- AL
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ namespace Org.OpenAPITools.Client
|
|||||||
return boolean
|
return boolean
|
||||||
? "true"
|
? "true"
|
||||||
: "false";
|
: "false";
|
||||||
|
if (obj is AreaCode areaCode)
|
||||||
|
return AreaCodeValueConverter.ToJsonValue(areaCode);
|
||||||
if (obj is MarineAreaCode marineAreaCode)
|
if (obj is MarineAreaCode marineAreaCode)
|
||||||
return MarineAreaCodeValueConverter.ToJsonValue(marineAreaCode);
|
return MarineAreaCodeValueConverter.ToJsonValue(marineAreaCode);
|
||||||
if (obj is StateTerritoryCode stateTerritoryCode)
|
if (obj is StateTerritoryCode stateTerritoryCode)
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ namespace Org.OpenAPITools.Client
|
|||||||
_jsonOptions.Converters.Add(new DateOnlyJsonConverter());
|
_jsonOptions.Converters.Add(new DateOnlyJsonConverter());
|
||||||
_jsonOptions.Converters.Add(new DateOnlyNullableJsonConverter());
|
_jsonOptions.Converters.Add(new DateOnlyNullableJsonConverter());
|
||||||
_jsonOptions.Converters.Add(new AreaCodeJsonConverter());
|
_jsonOptions.Converters.Add(new AreaCodeJsonConverter());
|
||||||
|
_jsonOptions.Converters.Add(new AreaCodeNullableJsonConverter());
|
||||||
_jsonOptions.Converters.Add(new MarineAreaCodeJsonConverter());
|
_jsonOptions.Converters.Add(new MarineAreaCodeJsonConverter());
|
||||||
_jsonOptions.Converters.Add(new MarineAreaCodeNullableJsonConverter());
|
_jsonOptions.Converters.Add(new MarineAreaCodeNullableJsonConverter());
|
||||||
_jsonOptions.Converters.Add(new StateTerritoryCodeJsonConverter());
|
_jsonOptions.Converters.Add(new StateTerritoryCodeJsonConverter());
|
||||||
|
|||||||
@@ -26,164 +26,178 @@ using Org.OpenAPITools.Client;
|
|||||||
namespace Org.OpenAPITools.Model
|
namespace Org.OpenAPITools.Model
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// AreaCode
|
/// Defines AreaCode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class AreaCode : IValidatableObject
|
public enum AreaCode
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="AreaCode" /> class.
|
/// Enum AL for value: AL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stateTerritoryCode"></param>
|
AL = 1,
|
||||||
internal AreaCode(StateTerritoryCode stateTerritoryCode)
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enum AK for value: AK
|
||||||
|
/// </summary>
|
||||||
|
AK = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enum AM for value: AM
|
||||||
|
/// </summary>
|
||||||
|
AM = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enum AN for value: AN
|
||||||
|
/// </summary>
|
||||||
|
AN = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts <see cref="AreaCode"/> to and from the JSON value
|
||||||
|
/// </summary>
|
||||||
|
public static class AreaCodeValueConverter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Parses a given value to <see cref="AreaCode"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static AreaCode FromString(string value)
|
||||||
{
|
{
|
||||||
StateTerritoryCode = stateTerritoryCode;
|
if (value.Equals("AL"))
|
||||||
OnCreated();
|
return AreaCode.AL;
|
||||||
|
|
||||||
|
if (value.Equals("AK"))
|
||||||
|
return AreaCode.AK;
|
||||||
|
|
||||||
|
if (value.Equals("AM"))
|
||||||
|
return AreaCode.AM;
|
||||||
|
|
||||||
|
if (value.Equals("AN"))
|
||||||
|
return AreaCode.AN;
|
||||||
|
|
||||||
|
throw new NotImplementedException($"Could not convert value to type AreaCode: '{value}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="AreaCode" /> class.
|
/// Parses a given value to <see cref="AreaCode"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="marineAreaCode"></param>
|
/// <param name="value"></param>
|
||||||
internal AreaCode(MarineAreaCode marineAreaCode)
|
/// <returns></returns>
|
||||||
|
public static AreaCode? FromStringOrDefault(string value)
|
||||||
{
|
{
|
||||||
MarineAreaCode = marineAreaCode;
|
if (value.Equals("AL"))
|
||||||
OnCreated();
|
return AreaCode.AL;
|
||||||
}
|
|
||||||
|
|
||||||
partial void OnCreated();
|
if (value.Equals("AK"))
|
||||||
|
return AreaCode.AK;
|
||||||
|
|
||||||
/// <summary>
|
if (value.Equals("AM"))
|
||||||
/// Gets or Sets StateTerritoryCode
|
return AreaCode.AM;
|
||||||
/// </summary>
|
|
||||||
public StateTerritoryCode? StateTerritoryCode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
if (value.Equals("AN"))
|
||||||
/// Gets or Sets MarineAreaCode
|
return AreaCode.AN;
|
||||||
/// </summary>
|
|
||||||
public MarineAreaCode? MarineAreaCode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
return null;
|
||||||
/// Returns the string presentation of the object
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>String presentation of the object</returns>
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.Append("class AreaCode {\n");
|
|
||||||
sb.Append("}\n");
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// To validate all properties of the instance
|
/// Converts the <see cref="AreaCode"/> to the json value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="validationContext">Validation context</param>
|
/// <param name="value"></param>
|
||||||
/// <returns>Validation Result</returns>
|
/// <returns></returns>
|
||||||
IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
|
public static string ToJsonValue(AreaCode value)
|
||||||
{
|
{
|
||||||
yield break;
|
if (value == AreaCode.AL)
|
||||||
|
return "AL";
|
||||||
|
|
||||||
|
if (value == AreaCode.AK)
|
||||||
|
return "AK";
|
||||||
|
|
||||||
|
if (value == AreaCode.AM)
|
||||||
|
return "AM";
|
||||||
|
|
||||||
|
if (value == AreaCode.AN)
|
||||||
|
return "AN";
|
||||||
|
|
||||||
|
throw new NotImplementedException($"Value could not be handled: '{value}'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Json converter for type <see cref="AreaCode" />
|
/// A Json converter for type <see cref="AreaCode"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <exception cref="NotImplementedException"></exception>
|
||||||
public class AreaCodeJsonConverter : JsonConverter<AreaCode>
|
public class AreaCodeJsonConverter : JsonConverter<AreaCode>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deserializes json to <see cref="AreaCode" />
|
/// Returns a from the Json object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="utf8JsonReader"></param>
|
/// <param name="reader"></param>
|
||||||
/// <param name="typeToConvert"></param>
|
/// <param name="typeToConvert"></param>
|
||||||
/// <param name="jsonSerializerOptions"></param>
|
/// <param name="options"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <exception cref="JsonException"></exception>
|
public override AreaCode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
public override AreaCode Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert, JsonSerializerOptions jsonSerializerOptions)
|
|
||||||
{
|
{
|
||||||
int currentDepth = utf8JsonReader.CurrentDepth;
|
string? rawValue = reader.GetString();
|
||||||
|
|
||||||
if (utf8JsonReader.TokenType != JsonTokenType.StartObject && utf8JsonReader.TokenType != JsonTokenType.StartArray)
|
AreaCode? result = rawValue == null
|
||||||
throw new JsonException();
|
? null
|
||||||
|
: AreaCodeValueConverter.FromStringOrDefault(rawValue);
|
||||||
|
|
||||||
JsonTokenType startingTokenType = utf8JsonReader.TokenType;
|
if (result != null)
|
||||||
|
return result.Value;
|
||||||
StateTerritoryCode? stateTerritoryCode = default;
|
|
||||||
MarineAreaCode? marineAreaCode = default;
|
|
||||||
|
|
||||||
Utf8JsonReader utf8JsonReaderOneOf = utf8JsonReader;
|
|
||||||
while (utf8JsonReaderOneOf.Read())
|
|
||||||
{
|
|
||||||
if (startingTokenType == JsonTokenType.StartObject && utf8JsonReaderOneOf.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReaderOneOf.CurrentDepth)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (startingTokenType == JsonTokenType.StartArray && utf8JsonReaderOneOf.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReaderOneOf.CurrentDepth)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (utf8JsonReaderOneOf.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReaderOneOf.CurrentDepth - 1)
|
|
||||||
{
|
|
||||||
Utf8JsonReader utf8JsonReaderStateTerritoryCode = utf8JsonReader;
|
|
||||||
ClientUtils.TryDeserialize<StateTerritoryCode?>(ref utf8JsonReaderStateTerritoryCode, jsonSerializerOptions, out stateTerritoryCode);
|
|
||||||
|
|
||||||
Utf8JsonReader utf8JsonReaderMarineAreaCode = utf8JsonReader;
|
|
||||||
ClientUtils.TryDeserialize<MarineAreaCode?>(ref utf8JsonReaderMarineAreaCode, jsonSerializerOptions, out marineAreaCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (utf8JsonReader.Read())
|
|
||||||
{
|
|
||||||
if (startingTokenType == JsonTokenType.StartObject && utf8JsonReader.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReader.CurrentDepth)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (startingTokenType == JsonTokenType.StartArray && utf8JsonReader.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReader.CurrentDepth)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (utf8JsonReader.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReader.CurrentDepth - 1)
|
|
||||||
{
|
|
||||||
string? localVarJsonPropertyName = utf8JsonReader.GetString();
|
|
||||||
utf8JsonReader.Read();
|
|
||||||
|
|
||||||
switch (localVarJsonPropertyName)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stateTerritoryCode != null)
|
|
||||||
return new AreaCode(stateTerritoryCode.Value);
|
|
||||||
|
|
||||||
if (marineAreaCode != null)
|
|
||||||
return new AreaCode(marineAreaCode.Value);
|
|
||||||
|
|
||||||
throw new JsonException();
|
throw new JsonException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serializes a <see cref="AreaCode" />
|
/// Writes the AreaCode to the json writer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="writer"></param>
|
/// <param name="writer"></param>
|
||||||
/// <param name="areaCode"></param>
|
/// <param name="areaCode"></param>
|
||||||
/// <param name="jsonSerializerOptions"></param>
|
/// <param name="options"></param>
|
||||||
/// <exception cref="NotImplementedException"></exception>
|
public override void Write(Utf8JsonWriter writer, AreaCode areaCode, JsonSerializerOptions options)
|
||||||
public override void Write(Utf8JsonWriter writer, AreaCode areaCode, JsonSerializerOptions jsonSerializerOptions)
|
|
||||||
{
|
{
|
||||||
writer.WriteStartObject();
|
writer.WriteStringValue(AreaCodeValueConverter.ToJsonValue(areaCode).ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WriteProperties(writer, areaCode, jsonSerializerOptions);
|
/// <summary>
|
||||||
writer.WriteEndObject();
|
/// A Json converter for type <see cref="AreaCode"/>
|
||||||
|
/// </summary>
|
||||||
|
public class AreaCodeNullableJsonConverter : JsonConverter<AreaCode?>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a AreaCode from the Json object
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reader"></param>
|
||||||
|
/// <param name="typeToConvert"></param>
|
||||||
|
/// <param name="options"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override AreaCode? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
string? rawValue = reader.GetString();
|
||||||
|
|
||||||
|
AreaCode? result = rawValue == null
|
||||||
|
? null
|
||||||
|
: AreaCodeValueConverter.FromStringOrDefault(rawValue);
|
||||||
|
|
||||||
|
if (result != null)
|
||||||
|
return result.Value;
|
||||||
|
|
||||||
|
throw new JsonException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serializes the properties of <see cref="AreaCode" />
|
/// Writes the AreaCode to the json writer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="writer"></param>
|
/// <param name="writer"></param>
|
||||||
/// <param name="areaCode"></param>
|
/// <param name="areaCode"></param>
|
||||||
/// <param name="jsonSerializerOptions"></param>
|
/// <param name="options"></param>
|
||||||
/// <exception cref="NotImplementedException"></exception>
|
public override void Write(Utf8JsonWriter writer, AreaCode? areaCode, JsonSerializerOptions options)
|
||||||
public void WriteProperties(Utf8JsonWriter writer, AreaCode areaCode, JsonSerializerOptions jsonSerializerOptions)
|
|
||||||
{
|
{
|
||||||
|
writer.WriteStringValue(areaCode.HasValue ? AreaCodeValueConverter.ToJsonValue(areaCode.Value).ToString() : "null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,28 +2,16 @@
|
|||||||
|
|
||||||
oneOf enum strings
|
oneOf enum strings
|
||||||
|
|
||||||
## Properties
|
## Enum
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
* `A` (value: `'a'`)
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
|
|
||||||
## Example
|
* `B` (value: `'b'`)
|
||||||
|
|
||||||
```python
|
* `C` (value: `'c'`)
|
||||||
from petstore_api.models.one_of_enum_string import OneOfEnumString
|
|
||||||
|
|
||||||
# TODO update the JSON string below
|
* `D` (value: `'d'`)
|
||||||
json = "{}"
|
|
||||||
# create an instance of OneOfEnumString from a JSON string
|
|
||||||
one_of_enum_string_instance = OneOfEnumString.from_json(json)
|
|
||||||
# print the JSON string representation of the object
|
|
||||||
print(OneOfEnumString.to_json())
|
|
||||||
|
|
||||||
# convert the object into a dict
|
|
||||||
one_of_enum_string_dict = one_of_enum_string_instance.to_dict()
|
|
||||||
# create an instance of OneOfEnumString from a dict
|
|
||||||
one_of_enum_string_from_dict = OneOfEnumString.from_dict(one_of_enum_string_dict)
|
|
||||||
```
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,124 +14,26 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import json
|
import json
|
||||||
import pprint
|
from enum import Enum
|
||||||
from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator
|
from typing_extensions import Self
|
||||||
from typing import Any, List, Optional
|
|
||||||
from petstore_api.models.enum_string1 import EnumString1
|
|
||||||
from petstore_api.models.enum_string2 import EnumString2
|
|
||||||
from pydantic import StrictStr, Field
|
|
||||||
from typing import Union, List, Set, Optional, Dict
|
|
||||||
from typing_extensions import Literal, Self
|
|
||||||
|
|
||||||
ONEOFENUMSTRING_ONE_OF_SCHEMAS = ["EnumString1", "EnumString2"]
|
|
||||||
|
|
||||||
class OneOfEnumString(BaseModel):
|
class OneOfEnumString(str, Enum):
|
||||||
"""
|
"""
|
||||||
oneOf enum strings
|
oneOf enum strings
|
||||||
"""
|
"""
|
||||||
# data type: EnumString1
|
|
||||||
oneof_schema_1_validator: Optional[EnumString1] = None
|
|
||||||
# data type: EnumString2
|
|
||||||
oneof_schema_2_validator: Optional[EnumString2] = None
|
|
||||||
actual_instance: Optional[Union[EnumString1, EnumString2]] = None
|
|
||||||
one_of_schemas: Set[str] = { "EnumString1", "EnumString2" }
|
|
||||||
|
|
||||||
model_config = ConfigDict(
|
"""
|
||||||
validate_assignment=True,
|
allowed enum values
|
||||||
protected_namespaces=(),
|
"""
|
||||||
)
|
A = 'a'
|
||||||
|
B = 'b'
|
||||||
|
C = 'c'
|
||||||
def __init__(self, *args, **kwargs) -> None:
|
D = 'd'
|
||||||
if args:
|
|
||||||
if len(args) > 1:
|
|
||||||
raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`")
|
|
||||||
if kwargs:
|
|
||||||
raise ValueError("If a position argument is used, keyword arguments cannot be used.")
|
|
||||||
super().__init__(actual_instance=args[0])
|
|
||||||
else:
|
|
||||||
super().__init__(**kwargs)
|
|
||||||
|
|
||||||
@field_validator('actual_instance')
|
|
||||||
def actual_instance_must_validate_oneof(cls, v):
|
|
||||||
instance = OneOfEnumString.model_construct()
|
|
||||||
error_messages = []
|
|
||||||
match = 0
|
|
||||||
# validate data type: EnumString1
|
|
||||||
if not isinstance(v, EnumString1):
|
|
||||||
error_messages.append(f"Error! Input type `{type(v)}` is not `EnumString1`")
|
|
||||||
else:
|
|
||||||
match += 1
|
|
||||||
# validate data type: EnumString2
|
|
||||||
if not isinstance(v, EnumString2):
|
|
||||||
error_messages.append(f"Error! Input type `{type(v)}` is not `EnumString2`")
|
|
||||||
else:
|
|
||||||
match += 1
|
|
||||||
if match > 1:
|
|
||||||
# more than 1 match
|
|
||||||
raise ValueError("Multiple matches found when setting `actual_instance` in OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
|
||||||
elif match == 0:
|
|
||||||
# no match
|
|
||||||
raise ValueError("No match found when setting `actual_instance` in OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
|
||||||
else:
|
|
||||||
return v
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self:
|
|
||||||
return cls.from_json(json.dumps(obj))
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, json_str: str) -> Self:
|
def from_json(cls, json_str: str) -> Self:
|
||||||
"""Returns the object represented by the json string"""
|
"""Create an instance of OneOfEnumString from a JSON string"""
|
||||||
instance = cls.model_construct()
|
return cls(json.loads(json_str))
|
||||||
error_messages = []
|
|
||||||
match = 0
|
|
||||||
|
|
||||||
# deserialize data into EnumString1
|
|
||||||
try:
|
|
||||||
instance.actual_instance = EnumString1.from_json(json_str)
|
|
||||||
match += 1
|
|
||||||
except (ValidationError, ValueError) as e:
|
|
||||||
error_messages.append(str(e))
|
|
||||||
# deserialize data into EnumString2
|
|
||||||
try:
|
|
||||||
instance.actual_instance = EnumString2.from_json(json_str)
|
|
||||||
match += 1
|
|
||||||
except (ValidationError, ValueError) as e:
|
|
||||||
error_messages.append(str(e))
|
|
||||||
|
|
||||||
if match > 1:
|
|
||||||
# more than 1 match
|
|
||||||
raise ValueError("Multiple matches found when deserializing the JSON string into OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
|
||||||
elif match == 0:
|
|
||||||
# no match
|
|
||||||
raise ValueError("No match found when deserializing the JSON string into OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
|
||||||
else:
|
|
||||||
return instance
|
|
||||||
|
|
||||||
def to_json(self) -> str:
|
|
||||||
"""Returns the JSON representation of the actual instance"""
|
|
||||||
if self.actual_instance is None:
|
|
||||||
return "null"
|
|
||||||
|
|
||||||
if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json):
|
|
||||||
return self.actual_instance.to_json()
|
|
||||||
else:
|
|
||||||
return json.dumps(self.actual_instance)
|
|
||||||
|
|
||||||
def to_dict(self) -> Optional[Union[Dict[str, Any], EnumString1, EnumString2]]:
|
|
||||||
"""Returns the dict representation of the actual instance"""
|
|
||||||
if self.actual_instance is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict):
|
|
||||||
return self.actual_instance.to_dict()
|
|
||||||
else:
|
|
||||||
# primitive type
|
|
||||||
return self.actual_instance
|
|
||||||
|
|
||||||
def to_str(self) -> str:
|
|
||||||
"""Returns the string representation of the actual instance"""
|
|
||||||
return pprint.pformat(self.model_dump())
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -75,9 +75,6 @@ class WithNestedOneOf(BaseModel):
|
|||||||
# override the default output from pydantic by calling `to_dict()` of nested_pig
|
# override the default output from pydantic by calling `to_dict()` of nested_pig
|
||||||
if self.nested_pig:
|
if self.nested_pig:
|
||||||
_dict['nested_pig'] = self.nested_pig.to_dict()
|
_dict['nested_pig'] = self.nested_pig.to_dict()
|
||||||
# override the default output from pydantic by calling `to_dict()` of nested_oneof_enum_string
|
|
||||||
if self.nested_oneof_enum_string:
|
|
||||||
_dict['nested_oneof_enum_string'] = self.nested_oneof_enum_string.to_dict()
|
|
||||||
return _dict
|
return _dict
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -92,7 +89,7 @@ class WithNestedOneOf(BaseModel):
|
|||||||
_obj = cls.model_validate({
|
_obj = cls.model_validate({
|
||||||
"size": obj.get("size"),
|
"size": obj.get("size"),
|
||||||
"nested_pig": Pig.from_dict(obj["nested_pig"]) if obj.get("nested_pig") is not None else None,
|
"nested_pig": Pig.from_dict(obj["nested_pig"]) if obj.get("nested_pig") is not None else None,
|
||||||
"nested_oneof_enum_string": OneOfEnumString.from_dict(obj["nested_oneof_enum_string"]) if obj.get("nested_oneof_enum_string") is not None else None
|
"nested_oneof_enum_string": obj.get("nested_oneof_enum_string")
|
||||||
})
|
})
|
||||||
return _obj
|
return _obj
|
||||||
|
|
||||||
|
|||||||
@@ -2,27 +2,16 @@
|
|||||||
|
|
||||||
oneOf enum strings
|
oneOf enum strings
|
||||||
|
|
||||||
## Properties
|
## Enum
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
|
|
||||||
## Example
|
* `A` (value: `'a'`)
|
||||||
|
|
||||||
```python
|
* `B` (value: `'b'`)
|
||||||
from petstore_api.models.one_of_enum_string import OneOfEnumString
|
|
||||||
|
|
||||||
# TODO update the JSON string below
|
* `C` (value: `'c'`)
|
||||||
json = "{}"
|
|
||||||
# create an instance of OneOfEnumString from a JSON string
|
* `D` (value: `'d'`)
|
||||||
one_of_enum_string_instance = OneOfEnumString.from_json(json)
|
|
||||||
# print the JSON string representation of the object
|
|
||||||
print OneOfEnumString.to_json()
|
|
||||||
|
|
||||||
# convert the object into a dict
|
|
||||||
one_of_enum_string_dict = one_of_enum_string_instance.to_dict()
|
|
||||||
# create an instance of OneOfEnumString from a dict
|
|
||||||
one_of_enum_string_from_dict = OneOfEnumString.from_dict(one_of_enum_string_dict)
|
|
||||||
```
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,130 +12,31 @@
|
|||||||
""" # noqa: E501
|
""" # noqa: E501
|
||||||
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
from inspect import getfullargspec
|
|
||||||
import json
|
import json
|
||||||
import pprint
|
import pprint
|
||||||
import re # noqa: F401
|
import re # noqa: F401
|
||||||
|
from aenum import Enum, no_arg
|
||||||
|
|
||||||
from typing import Any, List, Optional
|
|
||||||
from pydantic import BaseModel, Field, StrictStr, ValidationError, validator
|
|
||||||
from petstore_api.models.enum_string1 import EnumString1
|
|
||||||
from petstore_api.models.enum_string2 import EnumString2
|
|
||||||
from typing import Union, Any, List, TYPE_CHECKING
|
|
||||||
from pydantic import StrictStr, Field
|
|
||||||
|
|
||||||
ONEOFENUMSTRING_ONE_OF_SCHEMAS = ["EnumString1", "EnumString2"]
|
|
||||||
|
|
||||||
class OneOfEnumString(BaseModel):
|
|
||||||
|
|
||||||
|
class OneOfEnumString(str, Enum):
|
||||||
"""
|
"""
|
||||||
oneOf enum strings
|
oneOf enum strings
|
||||||
"""
|
"""
|
||||||
# data type: EnumString1
|
|
||||||
oneof_schema_1_validator: Optional[EnumString1] = None
|
|
||||||
# data type: EnumString2
|
|
||||||
oneof_schema_2_validator: Optional[EnumString2] = None
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
actual_instance: Union[EnumString1, EnumString2]
|
|
||||||
else:
|
|
||||||
actual_instance: Any
|
|
||||||
one_of_schemas: List[str] = Field(ONEOFENUMSTRING_ONE_OF_SCHEMAS, const=True)
|
|
||||||
|
|
||||||
class Config:
|
"""
|
||||||
validate_assignment = True
|
allowed enum values
|
||||||
|
"""
|
||||||
def __init__(self, *args, **kwargs) -> None:
|
A = 'a'
|
||||||
if args:
|
B = 'b'
|
||||||
if len(args) > 1:
|
C = 'c'
|
||||||
raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`")
|
D = 'd'
|
||||||
if kwargs:
|
|
||||||
raise ValueError("If a position argument is used, keyword arguments cannot be used.")
|
|
||||||
super().__init__(actual_instance=args[0])
|
|
||||||
else:
|
|
||||||
super().__init__(**kwargs)
|
|
||||||
|
|
||||||
@validator('actual_instance')
|
|
||||||
def actual_instance_must_validate_oneof(cls, v):
|
|
||||||
instance = OneOfEnumString.construct()
|
|
||||||
error_messages = []
|
|
||||||
match = 0
|
|
||||||
# validate data type: EnumString1
|
|
||||||
if not isinstance(v, EnumString1):
|
|
||||||
error_messages.append(f"Error! Input type `{type(v)}` is not `EnumString1`")
|
|
||||||
else:
|
|
||||||
match += 1
|
|
||||||
# validate data type: EnumString2
|
|
||||||
if not isinstance(v, EnumString2):
|
|
||||||
error_messages.append(f"Error! Input type `{type(v)}` is not `EnumString2`")
|
|
||||||
else:
|
|
||||||
match += 1
|
|
||||||
if match > 1:
|
|
||||||
# more than 1 match
|
|
||||||
raise ValueError("Multiple matches found when setting `actual_instance` in OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
|
||||||
elif match == 0:
|
|
||||||
# no match
|
|
||||||
raise ValueError("No match found when setting `actual_instance` in OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
|
||||||
else:
|
|
||||||
return v
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls, obj: dict) -> OneOfEnumString:
|
|
||||||
return cls.from_json(json.dumps(obj))
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, json_str: str) -> OneOfEnumString:
|
def from_json(cls, json_str: str) -> OneOfEnumString:
|
||||||
"""Returns the object represented by the json string"""
|
"""Create an instance of OneOfEnumString from a JSON string"""
|
||||||
instance = OneOfEnumString.construct()
|
return OneOfEnumString(json.loads(json_str))
|
||||||
error_messages = []
|
|
||||||
match = 0
|
|
||||||
|
|
||||||
# deserialize data into EnumString1
|
|
||||||
try:
|
|
||||||
instance.actual_instance = EnumString1.from_json(json_str)
|
|
||||||
match += 1
|
|
||||||
except (ValidationError, ValueError) as e:
|
|
||||||
error_messages.append(str(e))
|
|
||||||
# deserialize data into EnumString2
|
|
||||||
try:
|
|
||||||
instance.actual_instance = EnumString2.from_json(json_str)
|
|
||||||
match += 1
|
|
||||||
except (ValidationError, ValueError) as e:
|
|
||||||
error_messages.append(str(e))
|
|
||||||
|
|
||||||
if match > 1:
|
|
||||||
# more than 1 match
|
|
||||||
raise ValueError("Multiple matches found when deserializing the JSON string into OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
|
||||||
elif match == 0:
|
|
||||||
# no match
|
|
||||||
raise ValueError("No match found when deserializing the JSON string into OneOfEnumString with oneOf schemas: EnumString1, EnumString2. Details: " + ", ".join(error_messages))
|
|
||||||
else:
|
|
||||||
return instance
|
|
||||||
|
|
||||||
def to_json(self) -> str:
|
|
||||||
"""Returns the JSON representation of the actual instance"""
|
|
||||||
if self.actual_instance is None:
|
|
||||||
return "null"
|
|
||||||
|
|
||||||
to_json = getattr(self.actual_instance, "to_json", None)
|
|
||||||
if callable(to_json):
|
|
||||||
return self.actual_instance.to_json()
|
|
||||||
else:
|
|
||||||
return json.dumps(self.actual_instance)
|
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
|
||||||
"""Returns the dict representation of the actual instance"""
|
|
||||||
if self.actual_instance is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
to_dict = getattr(self.actual_instance, "to_dict", None)
|
|
||||||
if callable(to_dict):
|
|
||||||
return self.actual_instance.to_dict()
|
|
||||||
else:
|
|
||||||
# primitive type
|
|
||||||
return self.actual_instance
|
|
||||||
|
|
||||||
def to_str(self) -> str:
|
|
||||||
"""Returns the string representation of the actual instance"""
|
|
||||||
return pprint.pformat(self.dict())
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -59,9 +59,6 @@ class WithNestedOneOf(BaseModel):
|
|||||||
# override the default output from pydantic by calling `to_dict()` of nested_pig
|
# override the default output from pydantic by calling `to_dict()` of nested_pig
|
||||||
if self.nested_pig:
|
if self.nested_pig:
|
||||||
_dict['nested_pig'] = self.nested_pig.to_dict()
|
_dict['nested_pig'] = self.nested_pig.to_dict()
|
||||||
# override the default output from pydantic by calling `to_dict()` of nested_oneof_enum_string
|
|
||||||
if self.nested_oneof_enum_string:
|
|
||||||
_dict['nested_oneof_enum_string'] = self.nested_oneof_enum_string.to_dict()
|
|
||||||
return _dict
|
return _dict
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -76,7 +73,7 @@ class WithNestedOneOf(BaseModel):
|
|||||||
_obj = WithNestedOneOf.parse_obj({
|
_obj = WithNestedOneOf.parse_obj({
|
||||||
"size": obj.get("size"),
|
"size": obj.get("size"),
|
||||||
"nested_pig": Pig.from_dict(obj.get("nested_pig")) if obj.get("nested_pig") is not None else None,
|
"nested_pig": Pig.from_dict(obj.get("nested_pig")) if obj.get("nested_pig") is not None else None,
|
||||||
"nested_oneof_enum_string": OneOfEnumString.from_dict(obj.get("nested_oneof_enum_string")) if obj.get("nested_oneof_enum_string") is not None else None
|
"nested_oneof_enum_string": obj.get("nested_oneof_enum_string")
|
||||||
})
|
})
|
||||||
return _obj
|
return _obj
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user