82 lines
2.7 KiB
Swift
82 lines
2.7 KiB
Swift
// ===----------------------------------------------------------------------===
|
|
//
|
|
// This source file is part of the DiscogsService open source project
|
|
//
|
|
// Copyright (c) 2026 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 a semantic version or not.
|
|
///
|
|
/// This validation rules follows the principles defined in the [Semantic Versioning 2.0.0 documentation](https://semver.org/spec/v2.0.0.html)
|
|
struct SemanticVersionValidationRule: 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: - Definitions
|
|
|
|
extension InputValidationRule where Self == SemanticVersionValidationRule {
|
|
|
|
// MARK: Constants
|
|
|
|
/// A validation rule that checks whether an input is semantic version or not.
|
|
static var semanticVersion: Self { .init() }
|
|
|
|
}
|
|
|
|
// MARK: - Helpers
|
|
|
|
private extension SemanticVersionValidationRule {
|
|
|
|
// 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 ``InputValidationError`` in case the validation failed.
|
|
func validate(input: String?) throws -> Bool {
|
|
guard let input else {
|
|
return false
|
|
}
|
|
|
|
guard input.fullyMatch(
|
|
pattern: .init(format: .Pattern.semanticVersioning)
|
|
) else {
|
|
throw InputValidationError.inputNotSemanticVersion
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
}
|
|
|
|
// MARK: - Constants
|
|
|
|
private extension String.Pattern {
|
|
/// A regular expression pattern that represents semantic version inputs.
|
|
///
|
|
/// This regular expression is based on the [suggested regular expression](https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string) of the *Semantic Versioning 2.0.0* documentation.
|
|
static let semanticVersioning = "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-((?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"
|
|
}
|