Skip to content

Commit afe0ffb

Browse files
committed
feat: add uuid validation rule
1 parent 1894286 commit afe0ffb

File tree

12 files changed

+146
-18
lines changed

12 files changed

+146
-18
lines changed

Examples/Core/Content.playground/Contents.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import ValidatorCore
77

8-
// 1. LengthValidationRule - validates string length
8+
/// 1. LengthValidationRule - validates string length
99
let lengthRule = LengthValidationRule(min: 3, max: 20, error: "Length must be 3-20 characters")
1010

1111
let shortString = "ab"
@@ -18,7 +18,7 @@ print("'\(validString)' is valid: \(lengthRule.validate(input: validString))") /
1818
print("'\(longString)' is valid: \(lengthRule.validate(input: longString))") // false
1919
print()
2020

21-
// 2. NonEmptyValidationRule - checks if string is not empty
21+
/// 2. NonEmptyValidationRule - checks if string is not empty
2222
let nonEmptyRule = NonEmptyValidationRule(error: "Field is required")
2323

2424
let emptyString = ""
@@ -31,7 +31,7 @@ print("'\(whitespaceString)' is valid: \(nonEmptyRule.validate(input: whitespace
3131
print("'\(filledString)' is valid: \(nonEmptyRule.validate(input: filledString))") // true
3232
print()
3333

34-
// 3. PrefixValidationRule - validates string prefix
34+
/// 3. PrefixValidationRule - validates string prefix
3535
let prefixRule = PrefixValidationRule(prefix: "https://", error: "URL must start with https://")
3636

3737
let httpURL = "http://example.com"
@@ -44,7 +44,7 @@ print("'\(httpsURL)' is valid: \(prefixRule.validate(input: httpsURL))") // true
4444
print("'\(noProtocol)' is valid: \(prefixRule.validate(input: noProtocol))") // false
4545
print()
4646

47-
// 4. SuffixValidationRule - validates string suffix
47+
/// 4. SuffixValidationRule - validates string suffix
4848
let suffixRule = SuffixValidationRule(suffix: ".com", error: "Domain must end with .com")
4949

5050
let comDomain = "example.com"
@@ -57,7 +57,7 @@ print("'\(orgDomain)' is valid: \(suffixRule.validate(input: orgDomain))") // fa
5757
print("'\(noDomain)' is valid: \(suffixRule.validate(input: noDomain))") // false
5858
print()
5959

60-
// 5. RegexValidationRule - validates using regular expression
60+
/// 5. RegexValidationRule - validates using regular expression
6161
let phoneRule = RegexValidationRule(pattern: "^\\d{3}-\\d{4}$", error: "Invalid phone format")
6262

6363
let validPhone = "123-4567"
@@ -70,7 +70,7 @@ print("'\(invalidPhone1)' is valid: \(phoneRule.validate(input: invalidPhone1))"
7070
print("'\(invalidPhone2)' is valid: \(phoneRule.validate(input: invalidPhone2))") // false
7171
print()
7272

73-
// 6. URLValidationRule - validates URL format
73+
/// 6. URLValidationRule - validates URL format
7474
let urlRule = URLValidationRule(error: "Please enter a valid URL")
7575

7676
let validURL = "https://www.apple.com"
@@ -83,7 +83,7 @@ print("'\(invalidURL)' is valid: \(urlRule.validate(input: invalidURL))") // fal
8383
print("'\(localURL)' is valid: \(urlRule.validate(input: localURL))") // true
8484
print()
8585

86-
// 7. CreditCardValidationRule - validates credit card number (Luhn algorithm)
86+
/// 7. CreditCardValidationRule - validates credit card number (Luhn algorithm)
8787
let cardRule = CreditCardValidationRule(error: "Invalid card number")
8888

8989
let validCard = "4532015112830366" // Valid Visa test number
@@ -96,7 +96,7 @@ print("'\(invalidCard)' is valid: \(cardRule.validate(input: invalidCard))") //
9696
print("'\(shortCard)' is valid: \(cardRule.validate(input: shortCard))") // false
9797
print()
9898

99-
// 8. EmailValidationRule - validates email format
99+
/// 8. EmailValidationRule - validates email format
100100
let emailRule = EmailValidationRule(error: "Please enter a valid email")
101101

102102
let validEmail = "user@example.com"
@@ -109,7 +109,7 @@ print("'\(invalidEmail1)' is valid: \(emailRule.validate(input: invalidEmail1))"
109109
print("'\(invalidEmail2)' is valid: \(emailRule.validate(input: invalidEmail2))") // false
110110
print()
111111

112-
// 9. CharactersValidationRule - validates allowed characters
112+
/// 9. CharactersValidationRule - validates allowed characters
113113
let lettersRule = CharactersValidationRule(characterSet: .letters, error: "Invalid characters")
114114

115115
let onlyLetters = "HelloWorld"
@@ -122,7 +122,7 @@ print("'\(withNumbers)' is valid: \(lettersRule.validate(input: withNumbers))")
122122
print("'\(withSpaces)' is valid: \(lettersRule.validate(input: withSpaces))") // false
123123
print()
124124

125-
// 10. NilValidationRule - validates that value is nil
125+
/// 10. NilValidationRule - validates that value is nil
126126
let nilRule = NilValidationRule<String>(error: "Value must be nil")
127127

128128
let nilValue: String? = nil

Examples/Core/PlaygroundDependencies/Tests/PlaygroundDependenciesTests/PlaygroundDependenciesTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
@testable import PlaygroundDependencies
77
import Testing
88

9-
@Test func example() async throws {
9+
@Test func example() {
1010
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
1111
}

Examples/UIKit/UIKitExample/ViewControllers/LoginTextFieldExampleViewController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import ValidatorUI
1010
final class LoginTextFieldExampleViewController: UIViewController {
1111
// MARK: - Properties
1212

13-
// UI
13+
/// UI
1414
private let scrollView: UIScrollView = {
1515
let scrollView = UIScrollView()
1616
scrollView.translatesAutoresizingMaskIntoConstraints = false
@@ -67,7 +67,7 @@ final class LoginTextFieldExampleViewController: UIViewController {
6767
return stackView
6868
}()
6969

70-
// Private properties
70+
/// Private properties
7171
private var isValid: Bool {
7272
[firstNameTextField, lastNameTextField, emailTextField]
7373
.allSatisfy { $0.validationResult == .valid }

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ struct RegistrationView: View {
317317
| `IBANValidationRule` | Validates that a string is a valid IBAN (International Bank Account Number) | `IBANValidationRule(error: "Invalid IBAN")`
318318
| `IPAddressValidationRule` | Validates that a string is a valid IPv4 or IPv6 address | `IPAddressValidationRule(version: .v4, error: ValidationError("Invalid IPv4"))`
319319
| `PostalCodeValidationRule` | Validates postal/ZIP codes for different countries | `PostalCodeValidationRule(country: .uk, error: "Invalid post code")`
320+
| `UUIDValidationRule` | Validates UUID format | `UUIDValidationRule(error: "Please enter a valid UUID")` |
320321

321322
## Custom Validators
322323

Sources/ValidatorCore/Classes/Extensions/String+IValidationError.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,7 @@ import Foundation
2222
/// ```
2323
extension String: IValidationError {
2424
/// Returns the string itself as the error message.
25-
public var message: String { self }
25+
public var message: String {
26+
self
27+
}
2628
}

Sources/ValidatorCore/Classes/Rules/URLValidationRule.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import Foundation
1313
/// rule.validate(input: "https://example.com") // true
1414
/// rule.validate(input: "not_a_url") // false
1515
/// ```
16-
1716
public struct URLValidationRule: IValidationRule {
1817
// MARK: Types
1918

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// Validator
3+
// Copyright © 2026 Space Code. All rights reserved.
4+
//
5+
6+
import Foundation
7+
8+
/// Validates that a string represents a valid UUID.
9+
///
10+
/// # Example:
11+
/// ```swift
12+
/// let rule = UUIDValidationRule(error: "Invalid UUID")
13+
/// rule.validate(input: "47273ec2-e638-4702-8325-dcf82ed6a95b") // true
14+
/// rule.validate(input: "47273ec2") // false
15+
/// ```
16+
public struct UUIDValidationRule: IValidationRule {
17+
// MARK: Types
18+
19+
public typealias Input = String
20+
21+
// MARK: Properties
22+
23+
/// The validation error returned if the input is not a valid UUID.
24+
public let error: IValidationError
25+
26+
// MARK: Initialization
27+
28+
/// Initializes a URL validation rule.
29+
///
30+
/// - Parameter error: The validation error returned if input fails validation.
31+
public init(error: IValidationError) {
32+
self.error = error
33+
}
34+
35+
// MARK: IValidationRule
36+
37+
public func validate(input: String) -> Bool {
38+
UUID(uuidString: input) != nil
39+
}
40+
}

Sources/ValidatorCore/Validator.docc/Overview.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ ValidatorCore contains all core validation rules, utilities, and mechanisms for
4040
- ``IBANValidationRule``
4141
- ``IPAddressValidationRule``
4242
- ``PostalCodeValidationRule``
43+
- ``UUIDValidationRule``
4344

4445
### Articles
4546

Sources/ValidatorUI/Classes/AppKit/Extensions/NSTextField+Validation.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
extension NSTextField: IUIValidatable {
1010
/// The value of the text field to validate.
1111
/// Returns an empty string if `text` is nil.
12-
public var inputValue: String { stringValue }
12+
public var inputValue: String {
13+
stringValue
14+
}
1315

1416
/// The type of input for validation.
1517
public typealias Input = String

Sources/ValidatorUI/Classes/UIKit/Extensions/UITextField+Validation.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
extension UITextField: IUIValidatable {
1010
/// The value of the text field to validate.
1111
/// Returns an empty string if `text` is nil.
12-
public var inputValue: String { text ?? "" }
12+
public var inputValue: String {
13+
text ?? ""
14+
}
1315

1416
/// The type of input for validation.
1517
public typealias Input = String

0 commit comments

Comments
 (0)