Skip to content

Commit fb023b1

Browse files
authored
[swift5]Add array validation rule (#19242)
* Add ArrayRule * Run ./bin/utils/export_docs_generators.sh * Add ArrayValidationErrorKind * Add validation method * Run ./bin/generate-samples.sh * Add array rule property * Rename minItem and maxItem => minItems and maxItems * Fix uniqueItems template * Tweaks * Add sample property * Run ./bin/generate-samples.sh
1 parent 408706e commit fb023b1

File tree

25 files changed

+684
-1
lines changed

25 files changed

+684
-1
lines changed

modules/openapi-generator/src/main/resources/swift5/Validation.mustache

+35
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ import Foundation
2020
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var multipleOf: T?
2121
}
2222

23+
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} struct ArrayRule {
24+
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var minItems: Int?
25+
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var maxItems: Int?
26+
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var uniqueItems: Bool
27+
}
28+
2329
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} enum StringValidationErrorKind: Error {
2430
case minLength, maxLength, pattern
2531
}
@@ -28,6 +34,10 @@ import Foundation
2834
case minimum, maximum, multipleOf
2935
}
3036

37+
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} enum ArrayValidationErrorKind: Error {
38+
case minItems, maxItems, uniqueItems
39+
}
40+
3141
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} struct ValidationError<T: Error & Hashable>: Error {
3242
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} fileprivate(set) var kinds: Set<T>
3343
}
@@ -123,4 +133,29 @@ import Foundation
123133
}
124134
return numeric
125135
}
136+
137+
/// Validate a array against a rule.
138+
/// - Parameter array: The Array you wish to validate.
139+
/// - Parameter rule: The ArrayRule you wish to use for validation.
140+
/// - Returns: A validated array.
141+
/// - Throws: `ValidationError<ArrayValidationErrorKind>` if the string is invalid against the rule.
142+
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} static func validate(_ array: Array<AnyHashable>, against rule: ArrayRule) throws -> Array<AnyHashable> {
143+
var error = ValidationError<ArrayValidationErrorKind>(kinds: [])
144+
if let minItems = rule.minItems, !(minItems <= array.count) {
145+
error.kinds.insert(.minItems)
146+
}
147+
if let maxItems = rule.maxItems, !(array.count <= maxItems) {
148+
error.kinds.insert(.maxItems)
149+
}
150+
if rule.uniqueItems {
151+
let unique = Set(array)
152+
if unique.count != array.count {
153+
error.kinds.insert(.uniqueItems)
154+
}
155+
}
156+
guard error.kinds.isEmpty else {
157+
throw error
158+
}
159+
return array
160+
}
126161
}

modules/openapi-generator/src/main/resources/swift5/modelObject.mustache

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
{{#isNumeric}}
1717
static let {{{name}}}Rule = NumericRule<{{{dataType}}}>(minimum: {{#minimum}}{{{.}}}{{/minimum}}{{^minimum}}nil{{/minimum}}, exclusiveMinimum: {{#exclusiveMinimum}}true{{/exclusiveMinimum}}{{^exclusiveMinimum}}false{{/exclusiveMinimum}}, maximum: {{#maximum}}{{{.}}}{{/maximum}}{{^maximum}}nil{{/maximum}}, exclusiveMaximum: {{#exclusiveMaximum}}true{{/exclusiveMaximum}}{{^exclusiveMaximum}}false{{/exclusiveMaximum}}, multipleOf: {{#multipleOf}}{{{.}}}{{/multipleOf}}{{^multipleOf}}nil{{/multipleOf}})
1818
{{/isNumeric}}
19+
{{#isArray}}
20+
static let {{{name}}}Rule = ArrayRule(minItems: {{#minItems}}{{{.}}}{{/minItems}}{{^minItems}}nil{{/minItems}}, maxItems: {{#maxItems}}{{{.}}}{{/maxItems}}{{^maxItems}}nil{{/maxItems}}, uniqueItems: {{#uniqueItems}}true{{/uniqueItems}}{{^uniqueItems}}false{{/uniqueItems}})
21+
{{/isArray}}
1922
{{/hasValidation}}
2023
{{/validatable}}
2124
{{/allVars}}

modules/openapi-generator/src/test/resources/3_0/validation.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,10 @@ components:
2424
maximum: 100
2525
exclusiveMaximum: true
2626
multipleOf: 5
27+
ids:
28+
type: array
29+
items:
30+
type: integer
31+
minItems: 1
32+
maxItems: 10
33+
uniqueItems: false

samples/client/petstore/swift5/alamofireLibrary/PetstoreClient/Classes/OpenAPIs/Validation.swift

+35
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ public struct NumericRule<T: Comparable & Numeric> {
2020
public var multipleOf: T?
2121
}
2222

23+
public struct ArrayRule {
24+
public var minItems: Int?
25+
public var maxItems: Int?
26+
public var uniqueItems: Bool
27+
}
28+
2329
public enum StringValidationErrorKind: Error {
2430
case minLength, maxLength, pattern
2531
}
@@ -28,6 +34,10 @@ public enum NumericValidationErrorKind: Error {
2834
case minimum, maximum, multipleOf
2935
}
3036

37+
public enum ArrayValidationErrorKind: Error {
38+
case minItems, maxItems, uniqueItems
39+
}
40+
3141
public struct ValidationError<T: Error & Hashable>: Error {
3242
public fileprivate(set) var kinds: Set<T>
3343
}
@@ -123,4 +133,29 @@ public struct Validator {
123133
}
124134
return numeric
125135
}
136+
137+
/// Validate a array against a rule.
138+
/// - Parameter array: The Array you wish to validate.
139+
/// - Parameter rule: The ArrayRule you wish to use for validation.
140+
/// - Returns: A validated array.
141+
/// - Throws: `ValidationError<ArrayValidationErrorKind>` if the string is invalid against the rule.
142+
public static func validate(_ array: Array<AnyHashable>, against rule: ArrayRule) throws -> Array<AnyHashable> {
143+
var error = ValidationError<ArrayValidationErrorKind>(kinds: [])
144+
if let minItems = rule.minItems, !(minItems <= array.count) {
145+
error.kinds.insert(.minItems)
146+
}
147+
if let maxItems = rule.maxItems, !(array.count <= maxItems) {
148+
error.kinds.insert(.maxItems)
149+
}
150+
if rule.uniqueItems {
151+
let unique = Set(array)
152+
if unique.count != array.count {
153+
error.kinds.insert(.uniqueItems)
154+
}
155+
}
156+
guard error.kinds.isEmpty else {
157+
throw error
158+
}
159+
return array
160+
}
126161
}

samples/client/petstore/swift5/anycodableLibrary/PetstoreClient/Classes/OpenAPIs/Validation.swift

+35
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ public struct NumericRule<T: Comparable & Numeric> {
2020
public var multipleOf: T?
2121
}
2222

23+
public struct ArrayRule {
24+
public var minItems: Int?
25+
public var maxItems: Int?
26+
public var uniqueItems: Bool
27+
}
28+
2329
public enum StringValidationErrorKind: Error {
2430
case minLength, maxLength, pattern
2531
}
@@ -28,6 +34,10 @@ public enum NumericValidationErrorKind: Error {
2834
case minimum, maximum, multipleOf
2935
}
3036

37+
public enum ArrayValidationErrorKind: Error {
38+
case minItems, maxItems, uniqueItems
39+
}
40+
3141
public struct ValidationError<T: Error & Hashable>: Error {
3242
public fileprivate(set) var kinds: Set<T>
3343
}
@@ -123,4 +133,29 @@ public struct Validator {
123133
}
124134
return numeric
125135
}
136+
137+
/// Validate a array against a rule.
138+
/// - Parameter array: The Array you wish to validate.
139+
/// - Parameter rule: The ArrayRule you wish to use for validation.
140+
/// - Returns: A validated array.
141+
/// - Throws: `ValidationError<ArrayValidationErrorKind>` if the string is invalid against the rule.
142+
public static func validate(_ array: Array<AnyHashable>, against rule: ArrayRule) throws -> Array<AnyHashable> {
143+
var error = ValidationError<ArrayValidationErrorKind>(kinds: [])
144+
if let minItems = rule.minItems, !(minItems <= array.count) {
145+
error.kinds.insert(.minItems)
146+
}
147+
if let maxItems = rule.maxItems, !(array.count <= maxItems) {
148+
error.kinds.insert(.maxItems)
149+
}
150+
if rule.uniqueItems {
151+
let unique = Set(array)
152+
if unique.count != array.count {
153+
error.kinds.insert(.uniqueItems)
154+
}
155+
}
156+
guard error.kinds.isEmpty else {
157+
throw error
158+
}
159+
return array
160+
}
126161
}

samples/client/petstore/swift5/asyncAwaitLibrary/PetstoreClient/Classes/OpenAPIs/Validation.swift

+35
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ public struct NumericRule<T: Comparable & Numeric> {
2020
public var multipleOf: T?
2121
}
2222

23+
public struct ArrayRule {
24+
public var minItems: Int?
25+
public var maxItems: Int?
26+
public var uniqueItems: Bool
27+
}
28+
2329
public enum StringValidationErrorKind: Error {
2430
case minLength, maxLength, pattern
2531
}
@@ -28,6 +34,10 @@ public enum NumericValidationErrorKind: Error {
2834
case minimum, maximum, multipleOf
2935
}
3036

37+
public enum ArrayValidationErrorKind: Error {
38+
case minItems, maxItems, uniqueItems
39+
}
40+
3141
public struct ValidationError<T: Error & Hashable>: Error {
3242
public fileprivate(set) var kinds: Set<T>
3343
}
@@ -123,4 +133,29 @@ public struct Validator {
123133
}
124134
return numeric
125135
}
136+
137+
/// Validate a array against a rule.
138+
/// - Parameter array: The Array you wish to validate.
139+
/// - Parameter rule: The ArrayRule you wish to use for validation.
140+
/// - Returns: A validated array.
141+
/// - Throws: `ValidationError<ArrayValidationErrorKind>` if the string is invalid against the rule.
142+
public static func validate(_ array: Array<AnyHashable>, against rule: ArrayRule) throws -> Array<AnyHashable> {
143+
var error = ValidationError<ArrayValidationErrorKind>(kinds: [])
144+
if let minItems = rule.minItems, !(minItems <= array.count) {
145+
error.kinds.insert(.minItems)
146+
}
147+
if let maxItems = rule.maxItems, !(array.count <= maxItems) {
148+
error.kinds.insert(.maxItems)
149+
}
150+
if rule.uniqueItems {
151+
let unique = Set(array)
152+
if unique.count != array.count {
153+
error.kinds.insert(.uniqueItems)
154+
}
155+
}
156+
guard error.kinds.isEmpty else {
157+
throw error
158+
}
159+
return array
160+
}
126161
}

samples/client/petstore/swift5/combineLibrary/PetstoreClient/Classes/OpenAPIs/Validation.swift

+35
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ public struct NumericRule<T: Comparable & Numeric> {
2020
public var multipleOf: T?
2121
}
2222

23+
public struct ArrayRule {
24+
public var minItems: Int?
25+
public var maxItems: Int?
26+
public var uniqueItems: Bool
27+
}
28+
2329
public enum StringValidationErrorKind: Error {
2430
case minLength, maxLength, pattern
2531
}
@@ -28,6 +34,10 @@ public enum NumericValidationErrorKind: Error {
2834
case minimum, maximum, multipleOf
2935
}
3036

37+
public enum ArrayValidationErrorKind: Error {
38+
case minItems, maxItems, uniqueItems
39+
}
40+
3141
public struct ValidationError<T: Error & Hashable>: Error {
3242
public fileprivate(set) var kinds: Set<T>
3343
}
@@ -123,4 +133,29 @@ public struct Validator {
123133
}
124134
return numeric
125135
}
136+
137+
/// Validate a array against a rule.
138+
/// - Parameter array: The Array you wish to validate.
139+
/// - Parameter rule: The ArrayRule you wish to use for validation.
140+
/// - Returns: A validated array.
141+
/// - Throws: `ValidationError<ArrayValidationErrorKind>` if the string is invalid against the rule.
142+
public static func validate(_ array: Array<AnyHashable>, against rule: ArrayRule) throws -> Array<AnyHashable> {
143+
var error = ValidationError<ArrayValidationErrorKind>(kinds: [])
144+
if let minItems = rule.minItems, !(minItems <= array.count) {
145+
error.kinds.insert(.minItems)
146+
}
147+
if let maxItems = rule.maxItems, !(array.count <= maxItems) {
148+
error.kinds.insert(.maxItems)
149+
}
150+
if rule.uniqueItems {
151+
let unique = Set(array)
152+
if unique.count != array.count {
153+
error.kinds.insert(.uniqueItems)
154+
}
155+
}
156+
guard error.kinds.isEmpty else {
157+
throw error
158+
}
159+
return array
160+
}
126161
}

samples/client/petstore/swift5/default/PetstoreClient/Classes/OpenAPIs/Models/Pet.swift

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public struct Pet: Codable, JSONEncodable, Hashable {
1717
case pending = "pending"
1818
case sold = "sold"
1919
}
20+
static let photoUrlsRule = ArrayRule(minItems: nil, maxItems: nil, uniqueItems: true)
2021
public var id: Int64?
2122
public var category: Category?
2223
public var name: String

samples/client/petstore/swift5/default/PetstoreClient/Classes/OpenAPIs/Validation.swift

+35
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ public struct NumericRule<T: Comparable & Numeric> {
2020
public var multipleOf: T?
2121
}
2222

23+
public struct ArrayRule {
24+
public var minItems: Int?
25+
public var maxItems: Int?
26+
public var uniqueItems: Bool
27+
}
28+
2329
public enum StringValidationErrorKind: Error {
2430
case minLength, maxLength, pattern
2531
}
@@ -28,6 +34,10 @@ public enum NumericValidationErrorKind: Error {
2834
case minimum, maximum, multipleOf
2935
}
3036

37+
public enum ArrayValidationErrorKind: Error {
38+
case minItems, maxItems, uniqueItems
39+
}
40+
3141
public struct ValidationError<T: Error & Hashable>: Error {
3242
public fileprivate(set) var kinds: Set<T>
3343
}
@@ -123,4 +133,29 @@ public struct Validator {
123133
}
124134
return numeric
125135
}
136+
137+
/// Validate a array against a rule.
138+
/// - Parameter array: The Array you wish to validate.
139+
/// - Parameter rule: The ArrayRule you wish to use for validation.
140+
/// - Returns: A validated array.
141+
/// - Throws: `ValidationError<ArrayValidationErrorKind>` if the string is invalid against the rule.
142+
public static func validate(_ array: Array<AnyHashable>, against rule: ArrayRule) throws -> Array<AnyHashable> {
143+
var error = ValidationError<ArrayValidationErrorKind>(kinds: [])
144+
if let minItems = rule.minItems, !(minItems <= array.count) {
145+
error.kinds.insert(.minItems)
146+
}
147+
if let maxItems = rule.maxItems, !(array.count <= maxItems) {
148+
error.kinds.insert(.maxItems)
149+
}
150+
if rule.uniqueItems {
151+
let unique = Set(array)
152+
if unique.count != array.count {
153+
error.kinds.insert(.uniqueItems)
154+
}
155+
}
156+
guard error.kinds.isEmpty else {
157+
throw error
158+
}
159+
return array
160+
}
126161
}

0 commit comments

Comments
 (0)