Implemented an input validation mechanism (#4)
This PR contains the work done to implement the `ValidateInputUseCase` use case and the `InputValidationRule` protocol, that is essential to define custom validation rules for inputs. In addition, the `NotEmptyValidationRule` and `NotNilValidationRule` rules have also been implemented. Reviewed-on: #4 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit was merged in pull request #4.
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
// ===----------------------------------------------------------------------===
|
||||
//
|
||||
// This source file is part of the DiscogsService open source project
|
||||
//
|
||||
// Copyright (c) 2025 Röck+Cöde VoF. and the DiscogsService project authors
|
||||
// Licensed under Apache license v2.0
|
||||
//
|
||||
// See LICENSE for license information
|
||||
// See CONTRIBUTORS for the list of DiscogsService project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// ===----------------------------------------------------------------------===
|
||||
|
||||
/// A representation of all the possible validation error that could be thrown while validating an input.
|
||||
enum InputValidationError: Error {
|
||||
/// An input is empty.
|
||||
case inputIsEmpty
|
||||
/// An input is nil.
|
||||
case inputIsNil
|
||||
}
|
||||
@@ -31,6 +31,8 @@ extension String {
|
||||
static let authConsumer = "Discogs \(String.Parameter.key)=%@, \(String.Parameter.secret)=%@"
|
||||
/// A format for the user authentication header.
|
||||
static let authUser = "Discogs \(String.Parameter.token)=%@"
|
||||
/// A format for the user agent header.
|
||||
static let userAgent = "%@/%@ +%@"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// ===----------------------------------------------------------------------===
|
||||
//
|
||||
// This source file is part of the DiscogsService open source project
|
||||
//
|
||||
// Copyright (c) 2025 Röck+Cöde VoF. and the DiscogsService project authors
|
||||
// Licensed under Apache license v2.0
|
||||
//
|
||||
// See LICENSE for license information
|
||||
// See CONTRIBUTORS for the list of DiscogsService project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// ===----------------------------------------------------------------------===
|
||||
|
||||
/// A protocol that defines an input validation rule to be applied to an input by the ``ValidateInputUseCase`` use case.
|
||||
protocol InputValidationRule {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
#if swift(>=6.0)
|
||||
/// Validates a given input against a validation rule.
|
||||
/// - Parameter input: An input to be validated.
|
||||
/// - Returns: A flag that indicates whether an input has been validated or not.
|
||||
/// - Throws: An error of type ``InputValidationError`` in case a given input failed a validation.
|
||||
@discardableResult func validate(_ input: String?) throws(InputValidationError) -> Bool
|
||||
#else
|
||||
/// Validates a given input against a validation rule.
|
||||
/// - Parameter input: An input to be validated.
|
||||
/// - Returns: A flag that indicates whether an input has been validated or not.
|
||||
/// - Throws: An error of type ``InputValidationError`` in case a given input failed a validation.
|
||||
@discardableResult func validate(_ input: String?) throws -> Bool
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// ===----------------------------------------------------------------------===
|
||||
//
|
||||
// This source file is part of the DiscogsService open source project
|
||||
//
|
||||
// Copyright (c) 2025 Röck+Cöde VoF. and the DiscogsService project authors
|
||||
// Licensed under Apache license v2.0
|
||||
//
|
||||
// See LICENSE for license information
|
||||
// See CONTRIBUTORS for the list of DiscogsService project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// ===----------------------------------------------------------------------===
|
||||
|
||||
/// A use case that validates an input against a set of validation rules.
|
||||
struct ValidateInputUseCase {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A list of validation rules to match an input against.
|
||||
private let rules: [any InputValidationRule]
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
/// Initializes this use case.
|
||||
/// - Parameter rules: A list of validation rules to match an input against.
|
||||
init(rules: any InputValidationRule...) {
|
||||
self.rules = rules
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
#if swift(>=6.0)
|
||||
/// Validates an input against a set of validation rules.
|
||||
/// - Parameter input: An input to be validated against a set of rules, if any.
|
||||
/// - Throws: An error of type ``InputValidationError`` in case an input failed any validation.
|
||||
func callAsFunction(_ input: String?) throws(InputValidationError) {
|
||||
for rule in rules {
|
||||
try rule.validate(input)
|
||||
}
|
||||
}
|
||||
#else
|
||||
/// Validates an input against a set of validation rules.
|
||||
/// - Parameter input: An input to be validated against a set of rules, if any.
|
||||
/// - Throws: An error of type ``InputValidationError`` in case an input failed any validation.
|
||||
func callAsFunction(_ input: String?) throws {
|
||||
for rule in rules {
|
||||
try rule.validate(input)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// ===----------------------------------------------------------------------===
|
||||
//
|
||||
// This source file is part of the DiscogsService open source project
|
||||
//
|
||||
// Copyright (c) 2025 Röck+Cöde VoF. and the DiscogsService project authors
|
||||
// Licensed under Apache license v2.0
|
||||
//
|
||||
// See LICENSE for license information
|
||||
// See CONTRIBUTORS for the list of DiscogsService project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// ===----------------------------------------------------------------------===
|
||||
|
||||
/// A validation rule type that checks whether an input is empty or not.
|
||||
struct NotEmptyValidationRule: InputValidationRule {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
#if swift(>=6.0)
|
||||
func validate(_ input: String?) throws(InputValidationError) -> Bool {
|
||||
try validate(input: input)
|
||||
}
|
||||
#else
|
||||
func validate(_ input: String?) throws -> Bool {
|
||||
try validate(input: input)
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private extension NotEmptyValidationRule {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
/// Validates a given input.
|
||||
///
|
||||
/// > note: This helper function would not be necessary when support for *Swift 5.10* is discontinued.
|
||||
///
|
||||
/// - Parameter input: An input to be validated.
|
||||
/// - Returns: A flag that indicates whether a given input has been validated or not.
|
||||
/// - Throws: An error of type ``InputValidatorError`` in case the validation failed.
|
||||
func validate(input: String?) throws -> Bool {
|
||||
guard let input else {
|
||||
return false
|
||||
}
|
||||
guard !input.isEmpty else {
|
||||
throw InputValidationError.inputIsEmpty
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
extension InputValidationRule where Self == NotEmptyValidationRule {
|
||||
/// A validation rule that checks whether an input is empty or not.
|
||||
static var notEmpty: Self { .init() }
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// ===----------------------------------------------------------------------===
|
||||
//
|
||||
// This source file is part of the DiscogsService open source project
|
||||
//
|
||||
// Copyright (c) 2025 Röck+Cöde VoF. and the DiscogsService project authors
|
||||
// Licensed under Apache license v2.0
|
||||
//
|
||||
// See LICENSE for license information
|
||||
// See CONTRIBUTORS for the list of DiscogsService project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// ===----------------------------------------------------------------------===
|
||||
|
||||
/// A validation rule type that checks whether an input is nil or not.
|
||||
struct NotNilValidationRule: InputValidationRule {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
#if swift(>=6.0)
|
||||
func validate(_ input: String?) throws(InputValidationError) -> Bool {
|
||||
try validate(input: input)
|
||||
}
|
||||
#else
|
||||
func validate(_ input: String?) throws -> Bool {
|
||||
try validate(input: input)
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private extension NotNilValidationRule {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
/// Validates a given input.
|
||||
///
|
||||
/// > note: This helper function would not be necessary when support for *Swift 5.10* is discontinued.
|
||||
///
|
||||
/// - Parameter input: An input to be validated.
|
||||
/// - Returns: A flag that indicates whether a given input has been validated or not.
|
||||
/// - Throws: An error of type ``InputValidatorError`` in case the validation failed.
|
||||
func validate(input: String?) throws -> Bool {
|
||||
guard let input else {
|
||||
throw InputValidationError.inputIsNil
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
extension InputValidationRule where Self == NotNilValidationRule {
|
||||
/// A validation rule that checks whether an input is nil or not.
|
||||
static var notNil: Self { .init() }
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// ===----------------------------------------------------------------------===
|
||||
//
|
||||
// This source file is part of the DiscogsService open source project
|
||||
//
|
||||
// Copyright (c) 2025 Röck+Cöde VoF. and the DiscogsService project authors
|
||||
// Licensed under Apache license v2.0
|
||||
//
|
||||
// See LICENSE for license information
|
||||
// See CONTRIBUTORS for the list of DiscogsService project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// ===----------------------------------------------------------------------===
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A type that represents a product that uses the ``Client`` client.
|
||||
public struct Product: Sendable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A camel-cased name of a product.
|
||||
let name: String
|
||||
|
||||
/// A URI link related to a product.
|
||||
let url: String
|
||||
|
||||
/// A semantic version of a product.
|
||||
let version: String
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
/// Initializes this model.
|
||||
/// - Parameters:
|
||||
/// - name: A camel-cased name of a product.
|
||||
/// - version: A URI link related to a product.
|
||||
/// - url: A semantic version of a product.
|
||||
public init(
|
||||
name: String,
|
||||
version: String,
|
||||
url: String
|
||||
) {
|
||||
self.name = name
|
||||
self.url = url
|
||||
self.version = version
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user