Skip to content

Commit

Permalink
Merge pull request #102 from adam-fowler/validation
Browse files Browse the repository at this point in the history
Add validation code to AWSShape
  • Loading branch information
adam-fowler authored Aug 17, 2019
2 parents e566b4d + d4e7e0a commit 9c8c87d
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Sources/AWSSDKSwiftCore/AWSClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ extension AWSClient {
var body: Body = .empty
var queryParams: [String: Any] = [:]

// validate input parameters
try input.validate()

guard let baseURL = URL(string: "\(endpoint)"), let _ = baseURL.hostWithPort else {
throw RequestError.invalidURL("\(endpoint) must specify url host and scheme")
}
Expand Down
73 changes: 73 additions & 0 deletions Sources/AWSSDKSwiftCore/Doc/AWSShape.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public protocol AWSShape: Codable, XMLContainerCodingMap {
static var payloadPath: String? { get }
static var _xmlNamespace: String? { get }
static var _members: [AWSShapeMember] { get }

func validate(name: String) throws
}

extension AWSShape {
Expand Down Expand Up @@ -95,6 +97,77 @@ extension AWSShape {
}
return false
}

}

/// Validation code to add to AWSShape
extension AWSShape {
public func validate() throws {
try validate(name: "\(type(of:self))")
}

/// stub function for all shapes
public func validate(name: String) throws {
}

public func validate<T : BinaryInteger>(_ value: T, name: String, parent: String, min: T) throws {
guard value >= min else { throw AWSClientError.validationError(message: "\(parent).\(name) (\(value)) is less than minimum allowed value \(min).") }
}
public func validate<T : BinaryInteger>(_ value: T, name: String, parent: String, max: T) throws {
guard value <= max else { throw AWSClientError.validationError(message: "\(parent).\(name) (\(value)) is greater than the maximum allowed value \(max).") }
}
public func validate<T : FloatingPoint>(_ value: T, name: String, parent: String, min: T) throws {
guard value >= min else { throw AWSClientError.validationError(message: "\(parent).\(name) (\(value)) is less than minimum allowed value \(min).") }
}
public func validate<T : FloatingPoint>(_ value: T, name: String, parent: String, max: T) throws {
guard value <= max else { throw AWSClientError.validationError(message: "\(parent).\(name) (\(value)) is greater than the maximum allowed value \(max).") }
}
public func validate<T : Collection>(_ value: T, name: String, parent: String, min: Int) throws {
guard value.count >= min else { throw AWSClientError.validationError(message: "Length of \(parent).\(name) (\(value)) is less than minimum allowed value \(min).") }
}
public func validate<T : Collection>(_ value: T, name: String, parent: String, max: Int) throws {
guard value.count <= max else { throw AWSClientError.validationError(message: "Length of \(parent).\(name) (\(value)) is greater than the maximum allowed value \(max).") }
}
public func validate(_ value: String, name: String, parent: String, pattern: String) throws {
let regularExpression = try NSRegularExpression(pattern: pattern, options: [])
let firstMatch = regularExpression.rangeOfFirstMatch(in: value, options: .anchored, range: NSMakeRange(0, value.count))
guard firstMatch.location != NSNotFound && firstMatch.length == value.count else { throw AWSClientError.validationError(message: "\(parent).\(name) (\(value)) does not match pattern \(pattern).") }
}
// optional values
public func validate<T : BinaryInteger>(_ value: T?, name: String, parent: String, min: T) throws {
guard let value = value else {return}
try validate(value, name: name, parent: parent, min: min)
}
public func validate<T : BinaryInteger>(_ value: T?, name: String, parent: String, max: T) throws {
guard let value = value else {return}
try validate(value, name: name, parent: parent, max: max)
}
public func validate<T : FloatingPoint>(_ value: T?, name: String, parent: String, min: T) throws {
guard let value = value else {return}
try validate(value, name: name, parent: parent, min: min)
}
public func validate<T : FloatingPoint>(_ value: T?, name: String, parent: String, max: T) throws {
guard let value = value else {return}
try validate(value, name: name, parent: parent, max: max)
}
public func validate<T : Collection>(_ value: T?, name: String, parent: String, min: Int) throws {
guard let value = value else {return}
try validate(value, name: name, parent: parent, min: min)
}
public func validate<T : Collection>(_ value: T?, name: String, parent: String, max: Int) throws {
guard let value = value else {return}
try validate(value, name: name, parent: parent, max: max)
}
public func validate(_ value: String?, name: String, parent: String, pattern: String) throws {
guard let value = value else {return}
try validate(value, name: name, parent: parent, pattern: pattern)
}
}

extension AWSShape {
public static func idempotencyToken() -> String {
return UUID().uuidString
}
}

/// extension to CollectionEncoding to produce the XML equivalent class
Expand Down

0 comments on commit 9c8c87d

Please sign in to comment.