[feature][dart] Add support for uniqueItems/sets (#8375)

* [dart][dart-dio] Add support for set types

* copy `uniqueItems` usage from 2.0 fake spec to `3.0`
* add support for sets in parameters, responses and properties

* Regenerate all other samples

* Fix broken tests due to invalid cast

* Update documentation

* Regenerate samples

* update samples

Co-authored-by: William Cheng <wing328hk@gmail.com>
This commit is contained in:
Peter Leibiger
2021-02-02 11:42:45 +01:00
committed by GitHub
parent f01ee4a8d2
commit 769b0e0e38
51 changed files with 219 additions and 86 deletions

View File

@@ -41,8 +41,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|List|
|map|Map|
## LANGUAGE PRIMITIVES

View File

@@ -36,8 +36,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|List|
|map|Map|
## LANGUAGE PRIMITIVES

View File

@@ -34,8 +34,6 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|List|
|map|Map|
## LANGUAGE PRIMITIVES

View File

@@ -141,14 +141,13 @@ public class DartClientCodegen extends DefaultCodegen {
"double",
"dynamic"
);
instantiationTypes.put("array", "List");
instantiationTypes.put("map", "Map");
typeMapping = new HashMap<>();
typeMapping.put("Array", "List");
typeMapping.put("array", "List");
typeMapping.put("map", "Map");
typeMapping.put("List", "List");
typeMapping.put("set", "Set");
typeMapping.put("boolean", "bool");
typeMapping.put("string", "String");
typeMapping.put("char", "String");
@@ -468,9 +467,10 @@ public class DartClientCodegen extends DefaultCodegen {
@Override
public String toDefaultValue(Schema schema) {
if (ModelUtils.isMapSchema(schema)) {
if (ModelUtils.isMapSchema(schema) || ModelUtils.isSet(schema)) {
return "const {}";
} else if (ModelUtils.isArraySchema(schema)) {
}
if (ModelUtils.isArraySchema(schema)) {
return "const []";
}
@@ -494,7 +494,8 @@ public class DartClientCodegen extends DefaultCodegen {
if (ModelUtils.isArraySchema(target)) {
Schema<?> items = getSchemaItems((ArraySchema) schema);
return getSchemaType(target) + "<" + getTypeDeclaration(items) + ">";
} else if (ModelUtils.isMapSchema(target)) {
}
if (ModelUtils.isMapSchema(target)) {
// Note: ModelUtils.isMapSchema(p) returns true when p is a composed schema that also defines
// additionalproperties: true
Schema<?> inner = getAdditionalProperties(target);

View File

@@ -127,6 +127,9 @@ public class DartDioClientCodegen extends DartClientCodegen {
public String toDefaultValue(Schema schema) {
if (schema.getDefault() != null) {
if (ModelUtils.isArraySchema(schema)) {
if (ModelUtils.isSet(schema)) {
return "SetBuilder()";
}
return "ListBuilder()";
}
if (ModelUtils.isMapSchema(schema)) {
@@ -318,6 +321,7 @@ public class DartDioClientCodegen extends DartClientCodegen {
if (param.isContainer) {
final Map<String, Object> serializer = new HashMap<>();
serializer.put("isArray", param.isArray);
serializer.put("uniqueItems", param.uniqueItems);
serializer.put("isMap", param.isMap);
serializer.put("baseType", param.baseType);
serializers.add(serializer);
@@ -347,7 +351,8 @@ public class DartDioClientCodegen extends DartClientCodegen {
if (op.returnContainer != null) {
final Map<String, Object> serializer = new HashMap<>();
serializer.put("isArray", Objects.equals("array", op.returnContainer));
serializer.put("isArray", Objects.equals("array", op.returnContainer) || Objects.equals("set", op.returnContainer));
serializer.put("uniqueItems", op.uniqueItems);
serializer.put("isMap", Objects.equals("map", op.returnContainer));
serializer.put("baseType", op.returnBaseType);
serializers.add(serializer);

View File

@@ -69,7 +69,7 @@ class {{classname}} {
{{#isContainer}}
{{#isArray}}
const type = FullType(BuiltList, [FullType({{baseType}})]);
const type = FullType(Built{{#uniqueItems}}Built{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}, [FullType({{baseType}})]);
final serializedBody = _serializers.serialize({{paramName}}, specifiedType: type);
{{/isArray}}
{{#isMap}}
@@ -135,8 +135,7 @@ class {{classname}} {
{{/returnTypeIsPrimitive}}
{{/returnSimpleType}}
{{^returnSimpleType}}
const collectionType = {{#isMap}}BuiltMap{{/isMap}}{{^isMap}}BuiltList{{/isMap}};
const type = FullType(collectionType, [{{#isMap}}FullType(String), {{/isMap}}FullType({{{returnBaseType}}})]);
const type = FullType(Built{{#isMap}}Map{{/isMap}}{{#isArray}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}, [{{#isMap}}FullType(String), {{/isMap}}FullType({{{returnBaseType}}})]);
final data = _serializers.deserialize(
response.data is String
? jsonDecode(response.data as String)

View File

@@ -18,8 +18,8 @@ part 'serializers.g.dart';
Serializers serializers = (_$serializers.toBuilder(){{#apiInfo}}{{#apis}}{{#serializers}}
..addBuilderFactory(
{{#isArray}}
const FullType(BuiltList, [FullType({{baseType}})]),
() => ListBuilder<{{baseType}}>(),
const FullType(Built{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}, [FullType({{baseType}})]),
() => {{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}Builder<{{baseType}}>(),
{{/isArray}}
{{#isMap}}
const FullType(BuiltMap, [FullType(String), FullType({{baseType}})]),

View File

@@ -187,8 +187,8 @@ class {{{classname}}} {
if (response.body != null && response.statusCode != HttpStatus.noContent) {
{{#isArray}}
return (apiClient.deserialize(_decodeBodyBytes(response), '{{{returnType}}}') as List)
.map((item) => item as {{{returnBaseType}}})
.toList(growable: false);
.cast<{{{returnBaseType}}}>()
.{{#uniqueItems}}toSet(){{/uniqueItems}}{{^uniqueItems}}toList(growable: false){{/uniqueItems}};
{{/isArray}}
{{^isArray}}
{{#isMap}}

View File

@@ -194,6 +194,12 @@ class ApiClient {
.map((v) => _deserialize(v, newTargetType, growable: growable))
.toList(growable: true == growable);
}
if (value is Set && (match = _regSet.firstMatch(targetType)) != null) {
final newTargetType = match[1];
return value
.map((v) => _deserialize(v, newTargetType, growable: growable))
.toSet();
}
if (value is Map && (match = _regMap.firstMatch(targetType)) != null) {
final newTargetType = match[1];
return Map.fromIterables(

View File

@@ -26,6 +26,7 @@ const _delimiters = {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'};
const _dateEpochMarker = 'epoch';
final _dateFormatter = DateFormat('yyyy-MM-dd');
final _regList = RegExp(r'^List<(.*)>$');
final _regSet = RegExp(r'^Set<(.*)>$');
final _regMap = RegExp(r'^Map<String,(.*)>$');
ApiClient defaultApiClient = ApiClient();

View File

@@ -156,7 +156,7 @@ class {{{classname}}} {
{{^isEnum}}
{{{name}}}: json[r'{{{baseName}}}'] == null
? null
: (json[r'{{{baseName}}}'] as List).cast<{{{items.datatype}}}>(),
: (json[r'{{{baseName}}}'] as {{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}).cast<{{{items.datatype}}}>(),
{{/isEnum}}
{{/isArray}}
{{^isArray}}

View File

@@ -142,6 +142,45 @@ public class DartModelTest {
Assert.assertTrue(property2.isContainer);
}
@Test(description = "convert a model with set property")
public void setPropertyTest() {
final Schema model = new Schema()
.description("a sample model")
.addProperties("id", new IntegerSchema())
.addProperties("urls", new ArraySchema().items(new StringSchema()).uniqueItems(true))
.addRequiredItem("id");
final DefaultCodegen codegen = new DartClientCodegen();
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model);
codegen.setOpenAPI(openAPI);
final CodegenModel cm = codegen.fromModel("sample", model);
Assert.assertEquals(cm.name, "sample");
Assert.assertEquals(cm.classname, "Sample");
Assert.assertEquals(cm.description, "a sample model");
Assert.assertEquals(cm.vars.size(), 2);
final CodegenProperty property1 = cm.vars.get(0);
Assert.assertEquals(property1.baseName, "id");
Assert.assertEquals(property1.dataType, "int");
Assert.assertEquals(property1.name, "id");
Assert.assertNull(property1.defaultValue);
Assert.assertEquals(property1.baseType, "int");
Assert.assertTrue(property1.required);
Assert.assertTrue(property1.isPrimitiveType);
Assert.assertFalse(property1.isContainer);
final CodegenProperty property2 = cm.vars.get(1);
Assert.assertEquals(property2.baseName, "urls");
Assert.assertEquals(property2.dataType, "Set<String>");
Assert.assertEquals(property2.name, "urls");
Assert.assertEquals(property2.baseType, "Set");
Assert.assertEquals(property2.containerType, "set");
Assert.assertFalse(property2.required);
Assert.assertTrue(property2.isPrimitiveType);
Assert.assertTrue(property2.isContainer);
}
@Test(description = "convert a model with a map property")
public void mapPropertyTest() {
final Schema model = new Schema()

View File

@@ -204,6 +204,44 @@ public class DartDioModelTest {
Assert.assertTrue(property2.isContainer);
}
@Test(description = "convert a model with set property")
public void setPropertyTest() {
final Schema model = new Schema()
.description("a sample model")
.addProperties("id", new IntegerSchema())
.addProperties("urls", new ArraySchema().items(new StringSchema()).uniqueItems(true))
.addRequiredItem("id");
final DefaultCodegen codegen = new DartDioClientCodegen();
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model);
codegen.setOpenAPI(openAPI);
final CodegenModel cm = codegen.fromModel("sample", model);
Assert.assertEquals(cm.name, "sample");
Assert.assertEquals(cm.classname, "Sample");
Assert.assertEquals(cm.description, "a sample model");
Assert.assertEquals(cm.vars.size(), 2);
final CodegenProperty property1 = cm.vars.get(0);
Assert.assertEquals(property1.baseName, "id");
Assert.assertEquals(property1.dataType, "int");
Assert.assertEquals(property1.name, "id");
Assert.assertNull(property1.defaultValue);
Assert.assertEquals(property1.baseType, "int");
Assert.assertTrue(property1.required);
Assert.assertTrue(property1.isPrimitiveType);
Assert.assertFalse(property1.isContainer);
final CodegenProperty property2 = cm.vars.get(1);
Assert.assertEquals(property2.baseName, "urls");
Assert.assertEquals(property2.dataType, "BuiltSet<String>");
Assert.assertEquals(property2.name, "urls");
Assert.assertEquals(property2.baseType, "BuiltSet");
Assert.assertEquals(property2.containerType, "set");
Assert.assertFalse(property2.required);
Assert.assertTrue(property2.isPrimitiveType);
Assert.assertTrue(property2.isContainer);
}
@Test(description = "convert a model with a map property")
public void mapPropertyTest() {
final Schema model = new Schema()

View File

@@ -134,6 +134,7 @@ paths:
type: array
items:
type: string
uniqueItems: true
responses:
'200':
description: successful operation
@@ -143,11 +144,13 @@ paths:
type: array
items:
$ref: '#/components/schemas/Pet'
uniqueItems: true
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
uniqueItems: true
'400':
description: Invalid tag value
security:
@@ -1313,6 +1316,7 @@ components:
wrapped: true
items:
type: string
uniqueItems: true
tags:
type: array
xml:

View File

@@ -250,6 +250,8 @@ namespace Org.OpenAPITools.Model
/// <returns>Validation Result</returns>
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
yield break;
}
}

View File

@@ -181,8 +181,7 @@ class PetApi {
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
).then((response) {
const collectionType = BuiltList;
const type = FullType(collectionType, [FullType(Pet)]);
const type = FullType(BuiltList, [FullType(Pet)]);
final data = _serializers.deserialize(
response.data is String
? jsonDecode(response.data as String)
@@ -252,8 +251,7 @@ class PetApi {
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
).then((response) {
const collectionType = BuiltList;
const type = FullType(collectionType, [FullType(Pet)]);
const type = FullType(BuiltList, [FullType(Pet)]);
final data = _serializers.deserialize(
response.data is String
? jsonDecode(response.data as String)

View File

@@ -113,8 +113,7 @@ class StoreApi {
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
).then((response) {
const collectionType = BuiltMap;
const type = FullType(collectionType, [FullType(String), FullType(int)]);
const type = FullType(BuiltMap, [FullType(String), FullType(int)]);
final data = _serializers.deserialize(
response.data is String
? jsonDecode(response.data as String)

View File

@@ -41,6 +41,7 @@ const _delimiters = {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'};
const _dateEpochMarker = 'epoch';
final _dateFormatter = DateFormat('yyyy-MM-dd');
final _regList = RegExp(r'^List<(.*)>$');
final _regSet = RegExp(r'^Set<(.*)>$');
final _regMap = RegExp(r'^Map<String,(.*)>$');
ApiClient defaultApiClient = ApiClient();

View File

@@ -222,7 +222,7 @@ class PetApi {
// FormatException when trying to decode an empty string.
if (response.body != null && response.statusCode != HttpStatus.noContent) {
return (apiClient.deserialize(_decodeBodyBytes(response), 'List<Pet>') as List)
.map((item) => item as Pet)
.cast<Pet>()
.toList(growable: false);
}
return null;
@@ -300,7 +300,7 @@ class PetApi {
// FormatException when trying to decode an empty string.
if (response.body != null && response.statusCode != HttpStatus.noContent) {
return (apiClient.deserialize(_decodeBodyBytes(response), 'List<Pet>') as List)
.map((item) => item as Pet)
.cast<Pet>()
.toList(growable: false);
}
return null;

View File

@@ -188,6 +188,12 @@ class ApiClient {
.map((v) => _deserialize(v, newTargetType, growable: growable))
.toList(growable: true == growable);
}
if (value is Set && (match = _regSet.firstMatch(targetType)) != null) {
final newTargetType = match[1];
return value
.map((v) => _deserialize(v, newTargetType, growable: growable))
.toSet();
}
if (value is Map && (match = _regMap.firstMatch(targetType)) != null) {
final newTargetType = match[1];
return Map.fromIterables(

View File

@@ -1055,6 +1055,7 @@ class PetApi
);
}
$resourcePath = '/pet/findByTags';
$formParams = [];
$queryParams = [];

View File

@@ -362,6 +362,8 @@ class Pet implements ModelInterface, ArrayAccess, \JsonSerializable
*/
public function setPhotoUrls($photo_urls)
{
$this->container['photo_urls'] = $photo_urls;
return $this;

View File

@@ -154,6 +154,16 @@ module Petstore
true
end
# Custom attribute writer method with validation
# @param [Object] photo_urls Value to be assigned
def photo_urls=(photo_urls)
if photo_urls.nil?
fail ArgumentError, 'photo_urls cannot be nil'
end
@photo_urls = photo_urls
end
# Custom attribute writer method checking allowed values (enum).
# @param [Object] status Object to be assigned
def status=(status)

View File

@@ -154,6 +154,16 @@ module Petstore
true
end
# Custom attribute writer method with validation
# @param [Object] photo_urls Value to be assigned
def photo_urls=(photo_urls)
if photo_urls.nil?
fail ArgumentError, 'photo_urls cannot be nil'
end
@photo_urls = photo_urls
end
# Custom attribute writer method checking allowed values (enum).
# @param [Object] status Object to be assigned
def status=(status)

View File

@@ -37,7 +37,7 @@ export interface FindPetsByStatusRequest {
}
export interface FindPetsByTagsRequest {
tags: Array<string>;
tags: Set<string>;
}
export interface GetPetByIdRequest {
@@ -203,7 +203,7 @@ export class PetApi extends runtime.BaseAPI {
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
* Finds Pets by tags
*/
async findPetsByTagsRaw(requestParameters: FindPetsByTagsRequest): Promise<runtime.ApiResponse<Array<Pet>>> {
async findPetsByTagsRaw(requestParameters: FindPetsByTagsRequest): Promise<runtime.ApiResponse<Set<Pet>>> {
if (requestParameters.tags === null || requestParameters.tags === undefined) {
throw new runtime.RequiredError('tags','Required parameter requestParameters.tags was null or undefined when calling findPetsByTags.');
}
@@ -239,7 +239,7 @@ export class PetApi extends runtime.BaseAPI {
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
* Finds Pets by tags
*/
async findPetsByTags(requestParameters: FindPetsByTagsRequest): Promise<Array<Pet>> {
async findPetsByTags(requestParameters: FindPetsByTagsRequest): Promise<Set<Pet>> {
const response = await this.findPetsByTagsRaw(requestParameters);
return await response.value();
}

View File

@@ -50,10 +50,10 @@ export interface Pet {
name: string;
/**
*
* @type {Array<string>}
* @type {Set<string>}
* @memberof Pet
*/
photoUrls: Array<string>;
photoUrls: Set<string>;
/**
*
* @type {Array<Tag>}

View File

@@ -198,8 +198,7 @@ class PetApi {
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
).then((response) {
const collectionType = BuiltList;
const type = FullType(collectionType, [FullType(Pet)]);
const type = FullType(BuiltList, [FullType(Pet)]);
final data = _serializers.deserialize(
response.data is String
? jsonDecode(response.data as String)
@@ -269,8 +268,7 @@ class PetApi {
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
).then((response) {
const collectionType = BuiltList;
const type = FullType(collectionType, [FullType(Pet)]);
const type = FullType(BuiltList, [FullType(Pet)]);
final data = _serializers.deserialize(
response.data is String
? jsonDecode(response.data as String)

View File

@@ -113,8 +113,7 @@ class StoreApi {
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
).then((response) {
const collectionType = BuiltMap;
const type = FullType(collectionType, [FullType(String), FullType(int)]);
const type = FullType(BuiltMap, [FullType(String), FullType(int)]);
final data = _serializers.deserialize(
response.data is String
? jsonDecode(response.data as String)

View File

@@ -11,7 +11,7 @@ Name | Type | Description | Notes
**id** | **int** | | [optional]
**category** | [**Category**](Category.md) | | [optional]
**name** | **String** | |
**photoUrls** | **BuiltList<String>** | |
**photoUrls** | **BuiltSet<String>** | |
**tags** | [**BuiltList<Tag>**](Tag.md) | | [optional]
**status** | **String** | pet status in the store | [optional]

View File

@@ -152,7 +152,7 @@ Name | Type | Description | Notes
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **findPetsByTags**
> BuiltList<Pet> findPetsByTags(tags)
> BuiltSet<Pet> findPetsByTags(tags)
Finds Pets by tags
@@ -165,7 +165,7 @@ import 'package:openapi/api.dart';
//defaultApiClient.getAuthentication<OAuth>('petstore_auth').accessToken = 'YOUR_ACCESS_TOKEN';
var api_instance = new PetApi();
var tags = []; // BuiltList<String> | Tags to filter by
var tags = []; // BuiltSet<String> | Tags to filter by
try {
var result = api_instance.findPetsByTags(tags);
@@ -179,11 +179,11 @@ try {
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**tags** | [**BuiltList<String>**](String.md)| Tags to filter by |
**tags** | [**BuiltSet<String>**](String.md)| Tags to filter by |
### Return type
[**BuiltList<Pet>**](Pet.md)
[**BuiltSet<Pet>**](Pet.md)
### Authorization

View File

@@ -181,8 +181,7 @@ class PetApi {
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
).then((response) {
const collectionType = BuiltList;
const type = FullType(collectionType, [FullType(Pet)]);
const type = FullType(BuiltList, [FullType(Pet)]);
final data = _serializers.deserialize(
response.data is String
? jsonDecode(response.data as String)
@@ -206,8 +205,8 @@ class PetApi {
/// Finds Pets by tags
///
/// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
Future<Response<BuiltList<Pet>>> findPetsByTags(
BuiltList<String> tags, {
Future<Response<BuiltSet<Pet>>> findPetsByTags(
BuiltSet<String> tags, {
CancelToken cancelToken,
Map<String, dynamic> headers,
Map<String, dynamic> extra,
@@ -252,16 +251,15 @@ class PetApi {
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
).then((response) {
const collectionType = BuiltList;
const type = FullType(collectionType, [FullType(Pet)]);
const type = FullType(BuiltSet, [FullType(Pet)]);
final data = _serializers.deserialize(
response.data is String
? jsonDecode(response.data as String)
: response.data,
specifiedType: type,
) as BuiltList<Pet>;
) as BuiltSet<Pet>;
return Response<BuiltList<Pet>>(
return Response<BuiltSet<Pet>>(
data: data,
headers: response.headers,
isRedirect: response.isRedirect,

View File

@@ -113,8 +113,7 @@ class StoreApi {
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
).then((response) {
const collectionType = BuiltMap;
const type = FullType(collectionType, [FullType(String), FullType(int)]);
const type = FullType(BuiltMap, [FullType(String), FullType(int)]);
final data = _serializers.deserialize(
response.data is String
? jsonDecode(response.data as String)

View File

@@ -29,7 +29,7 @@ abstract class Pet implements Built<Pet, PetBuilder> {
@nullable
@BuiltValueField(wireName: r'photoUrls')
BuiltList<String> get photoUrls;
BuiltSet<String> get photoUrls;
@nullable
@BuiltValueField(wireName: r'tags')

View File

@@ -109,6 +109,10 @@ Serializers serializers = (_$serializers.toBuilder()
const FullType(BuiltMap, [FullType(String), FullType(String)]),
() => MapBuilder<String, String>(),
)
..addBuilderFactory(
const FullType(BuiltSet, [FullType(Pet)]),
() => SetBuilder<Pet>(),
)
..addBuilderFactory(
const FullType(BuiltList, [FullType(Pet)]),
() => ListBuilder<Pet>(),

View File

@@ -35,7 +35,7 @@ void main() {
//
// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
//
//Future<BuiltList<Pet>> findPetsByTags(BuiltList<String> tags) async
//Future<BuiltSet<Pet>> findPetsByTags(BuiltSet<String> tags) async
test('test findPetsByTags', () async {
// TODO
});

View File

@@ -21,7 +21,7 @@ void main() {
// TODO
});
// BuiltList<String> photoUrls
// BuiltSet<String> photoUrls
test('to test the property `photoUrls`', () async {
// TODO
});

View File

@@ -41,6 +41,7 @@ const _delimiters = {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'};
const _dateEpochMarker = 'epoch';
final _dateFormatter = DateFormat('yyyy-MM-dd');
final _regList = RegExp(r'^List<(.*)>$');
final _regSet = RegExp(r'^Set<(.*)>$');
final _regMap = RegExp(r'^Map<String,(.*)>$');
ApiClient defaultApiClient = ApiClient();

View File

@@ -229,7 +229,7 @@ class PetApi {
// FormatException when trying to decode an empty string.
if (response.body != null && response.statusCode != HttpStatus.noContent) {
return (apiClient.deserialize(_decodeBodyBytes(response), 'List<Pet>') as List)
.map((item) => item as Pet)
.cast<Pet>()
.toList(growable: false);
}
return null;
@@ -307,7 +307,7 @@ class PetApi {
// FormatException when trying to decode an empty string.
if (response.body != null && response.statusCode != HttpStatus.noContent) {
return (apiClient.deserialize(_decodeBodyBytes(response), 'List<Pet>') as List)
.map((item) => item as Pet)
.cast<Pet>()
.toList(growable: false);
}
return null;

View File

@@ -188,6 +188,12 @@ class ApiClient {
.map((v) => _deserialize(v, newTargetType, growable: growable))
.toList(growable: true == growable);
}
if (value is Set && (match = _regSet.firstMatch(targetType)) != null) {
final newTargetType = match[1];
return value
.map((v) => _deserialize(v, newTargetType, growable: growable))
.toSet();
}
if (value is Map && (match = _regMap.firstMatch(targetType)) != null) {
final newTargetType = match[1];
return Map.fromIterables(

View File

@@ -11,7 +11,7 @@ Name | Type | Description | Notes
**id** | **int** | | [optional]
**category** | [**Category**](Category.md) | | [optional]
**name** | **String** | |
**photoUrls** | **List<String>** | | [default to const []]
**photoUrls** | **Set<String>** | | [default to const {}]
**tags** | [**List<Tag>**](Tag.md) | | [optional] [default to const []]
**status** | **String** | pet status in the store | [optional]

View File

@@ -152,7 +152,7 @@ Name | Type | Description | Notes
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **findPetsByTags**
> List<Pet> findPetsByTags(tags)
> Set<Pet> findPetsByTags(tags)
Finds Pets by tags
@@ -165,7 +165,7 @@ import 'package:openapi/api.dart';
//defaultApiClient.getAuthentication<OAuth>('petstore_auth').accessToken = 'YOUR_ACCESS_TOKEN';
final api_instance = PetApi();
final tags = []; // List<String> | Tags to filter by
final tags = []; // Set<String> | Tags to filter by
try {
final result = api_instance.findPetsByTags(tags);
@@ -179,11 +179,11 @@ try {
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**tags** | [**List<String>**](String.md)| Tags to filter by | [default to const []]
**tags** | [**Set<String>**](String.md)| Tags to filter by | [default to const {}]
### Return type
[**List<Pet>**](Pet.md)
[**Set<Pet>**](Pet.md)
### Authorization

View File

@@ -82,6 +82,7 @@ const _delimiters = {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'};
const _dateEpochMarker = 'epoch';
final _dateFormatter = DateFormat('yyyy-MM-dd');
final _regList = RegExp(r'^List<(.*)>$');
final _regSet = RegExp(r'^Set<(.*)>$');
final _regMap = RegExp(r'^Map<String,(.*)>$');
ApiClient defaultApiClient = ApiClient();

View File

@@ -222,7 +222,7 @@ class PetApi {
// FormatException when trying to decode an empty string.
if (response.body != null && response.statusCode != HttpStatus.noContent) {
return (apiClient.deserialize(_decodeBodyBytes(response), 'List<Pet>') as List)
.map((item) => item as Pet)
.cast<Pet>()
.toList(growable: false);
}
return null;
@@ -236,9 +236,9 @@ class PetApi {
///
/// Parameters:
///
/// * [List<String>] tags (required):
/// * [Set<String>] tags (required):
/// Tags to filter by
Future<Response> findPetsByTagsWithHttpInfo(List<String> tags) async {
Future<Response> findPetsByTagsWithHttpInfo(Set<String> tags) async {
// Verify required params are set.
if (tags == null) {
throw ApiException(HttpStatus.badRequest, 'Missing required param: tags');
@@ -288,9 +288,9 @@ class PetApi {
///
/// Parameters:
///
/// * [List<String>] tags (required):
/// * [Set<String>] tags (required):
/// Tags to filter by
Future<List<Pet>> findPetsByTags(List<String> tags) async {
Future<Set<Pet>> findPetsByTags(Set<String> tags) async {
final response = await findPetsByTagsWithHttpInfo(tags);
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, _decodeBodyBytes(response));
@@ -299,9 +299,9 @@ class PetApi {
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body != null && response.statusCode != HttpStatus.noContent) {
return (apiClient.deserialize(_decodeBodyBytes(response), 'List<Pet>') as List)
.map((item) => item as Pet)
.toList(growable: false);
return (apiClient.deserialize(_decodeBodyBytes(response), 'Set<Pet>') as List)
.cast<Pet>()
.toSet();
}
return null;
}

View File

@@ -265,6 +265,12 @@ class ApiClient {
.map((v) => _deserialize(v, newTargetType, growable: growable))
.toList(growable: true == growable);
}
if (value is Set && (match = _regSet.firstMatch(targetType)) != null) {
final newTargetType = match[1];
return value
.map((v) => _deserialize(v, newTargetType, growable: growable))
.toSet();
}
if (value is Map && (match = _regMap.firstMatch(targetType)) != null) {
final newTargetType = match[1];
return Map.fromIterables(

View File

@@ -15,7 +15,7 @@ class Pet {
this.id,
this.category,
@required this.name,
this.photoUrls = const [],
this.photoUrls = const {},
this.tags = const [],
this.status,
});
@@ -26,7 +26,7 @@ class Pet {
String name;
List<String> photoUrls;
Set<String> photoUrls;
List<Tag> tags;
@@ -87,7 +87,7 @@ class Pet {
name: json[r'name'],
photoUrls: json[r'photoUrls'] == null
? null
: (json[r'photoUrls'] as List).cast<String>(),
: (json[r'photoUrls'] as Set).cast<String>(),
tags: Tag.listFromJson(json[r'tags']),
status: PetStatusEnum.fromJson(json[r'status']),
);

View File

@@ -43,7 +43,7 @@ void main() {
//
// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
//
//Future<List<Pet>> findPetsByTags(List<String> tags) async
//Future<Set<Pet>> findPetsByTags(Set<String> tags) async
test('test findPetsByTags', () async {
// TODO
});

View File

@@ -21,7 +21,7 @@ void main() {
// TODO
});
// List<String> photoUrls (default value: const [])
// Set<String> photoUrls (default value: const {})
test('to test the property `photoUrls`', () async {
// TODO
});

View File

@@ -10,6 +10,7 @@ import io.swagger.jaxrs.*;
import java.io.File;
import org.openapitools.model.ModelApiResponse;
import org.openapitools.model.Pet;
import java.util.Set;
import java.util.Map;
import java.util.List;
@@ -115,17 +116,17 @@ public class PetApi {
@Path("/findByTags")
@Produces({ "application/xml", "application/json" })
@io.swagger.annotations.ApiOperation(value = "Finds Pets by tags", notes = "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", response = Pet.class, responseContainer = "List", authorizations = {
@io.swagger.annotations.ApiOperation(value = "Finds Pets by tags", notes = "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", response = Pet.class, responseContainer = "Set", authorizations = {
@io.swagger.annotations.Authorization(value = "petstore_auth", scopes = {
@io.swagger.annotations.AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
@io.swagger.annotations.AuthorizationScope(scope = "read:pets", description = "read your pets")
})
}, tags={ "pet", })
@io.swagger.annotations.ApiResponses(value = {
@io.swagger.annotations.ApiResponse(code = 200, message = "successful operation", response = Pet.class, responseContainer = "List"),
@io.swagger.annotations.ApiResponse(code = 200, message = "successful operation", response = Pet.class, responseContainer = "Set"),
@io.swagger.annotations.ApiResponse(code = 400, message = "Invalid tag value", response = Void.class)
})
public Response findPetsByTags(@ApiParam(value = "Tags to filter by", required = true) @QueryParam("tags") @NotNull @Valid List<String> tags,@Context SecurityContext securityContext)
public Response findPetsByTags(@ApiParam(value = "Tags to filter by", required = true) @QueryParam("tags") @NotNull @Valid Set<String> tags,@Context SecurityContext securityContext)
throws NotFoundException {
return delegate.findPetsByTags(tags, securityContext);
}

View File

@@ -8,6 +8,7 @@ import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import java.io.File;
import org.openapitools.model.ModelApiResponse;
import org.openapitools.model.Pet;
import java.util.Set;
import java.util.List;
import org.openapitools.api.NotFoundException;
@@ -22,7 +23,7 @@ public abstract class PetApiService {
public abstract Response addPet(Pet pet,SecurityContext securityContext) throws NotFoundException;
public abstract Response deletePet(Long petId,String apiKey,SecurityContext securityContext) throws NotFoundException;
public abstract Response findPetsByStatus( @NotNull List<String> status,SecurityContext securityContext) throws NotFoundException;
public abstract Response findPetsByTags( @NotNull List<String> tags,SecurityContext securityContext) throws NotFoundException;
public abstract Response findPetsByTags( @NotNull Set<String> tags,SecurityContext securityContext) throws NotFoundException;
public abstract Response getPetById(Long petId,SecurityContext securityContext) throws NotFoundException;
public abstract Response updatePet(Pet pet,SecurityContext securityContext) throws NotFoundException;
public abstract Response updatePetWithForm(Long petId,String name,String status,SecurityContext securityContext) throws NotFoundException;

View File

@@ -20,7 +20,9 @@ import com.fasterxml.jackson.annotation.JsonValue;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.openapitools.model.Category;
import org.openapitools.model.Tag;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@@ -54,7 +56,7 @@ public class Pet {
public static final String JSON_PROPERTY_PHOTO_URLS = "photoUrls";
@JsonProperty(JSON_PROPERTY_PHOTO_URLS)
private List<String> photoUrls = new ArrayList<String>();
private Set<String> photoUrls = new LinkedHashSet<String>();
public static final String JSON_PROPERTY_TAGS = "tags";
@JsonProperty(JSON_PROPERTY_TAGS)
@@ -157,7 +159,7 @@ public class Pet {
this.name = name;
}
public Pet photoUrls(List<String> photoUrls) {
public Pet photoUrls(Set<String> photoUrls) {
this.photoUrls = photoUrls;
return this;
}
@@ -174,11 +176,11 @@ public class Pet {
@JsonProperty("photoUrls")
@ApiModelProperty(required = true, value = "")
@NotNull
public List<String> getPhotoUrls() {
public Set<String> getPhotoUrls() {
return photoUrls;
}
public void setPhotoUrls(List<String> photoUrls) {
public void setPhotoUrls(Set<String> photoUrls) {
this.photoUrls = photoUrls;
}

View File

@@ -6,6 +6,7 @@ import org.openapitools.model.*;
import java.io.File;
import org.openapitools.model.ModelApiResponse;
import org.openapitools.model.Pet;
import java.util.Set;
import java.util.List;
import org.openapitools.api.NotFoundException;
@@ -35,7 +36,7 @@ public class PetApiServiceImpl extends PetApiService {
return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
}
@Override
public Response findPetsByTags( @NotNull List<String> tags, SecurityContext securityContext) throws NotFoundException {
public Response findPetsByTags( @NotNull Set<String> tags, SecurityContext securityContext) throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
}