Skip to content

Commit 3391a83

Browse files
authored
docs: add a documentation (#68)
1 parent 8c950f9 commit 3391a83

35 files changed

+1086
-82
lines changed

.github/workflows/docs.yml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: Deploy DocC Documentation
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
workflow_dispatch:
7+
inputs:
8+
version:
9+
description: 'Documentation version'
10+
required: false
11+
default: latest'
12+
13+
permissions:
14+
contents: write
15+
16+
concurrency:
17+
group: "pages"
18+
cancel-in-progress: true
19+
20+
jobs:
21+
deploy:
22+
runs-on: macos-14
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
27+
- name: Setup Xcode
28+
uses: maxim-lobanov/setup-xcode@v1
29+
with:
30+
xcode-version: latest-stable
31+
32+
- name: Get Version
33+
id: version
34+
run: |
35+
if [ -n "${{ github.event.inputs.version }}" ]; then
36+
VERSION="${{ github.event.inputs.version }}"
37+
else
38+
VERSION="latest"
39+
fi
40+
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
41+
echo "Building documentation for version: $VERSION"
42+
43+
- name: Build DocC
44+
id: build
45+
uses: space-code/build-docc@main
46+
with:
47+
schemes: '["ValidatorCore", "ValidatorUI"]'
48+
version: ${{ steps.version.outputs.version }}
49+
50+
- name: Generate Index Page
51+
uses: space-code/generate-index@v1.0.0
52+
with:
53+
version: ${{ steps.version.outputs.version }}
54+
project-name: 'Validator'
55+
project-description: 'Validator is a modern, lightweight Swift framework that provides elegant and type-safe input validation.'
56+
modules: |
57+
[
58+
{
59+
"name": "ValidatorCore",
60+
"path": "validatorcore",
61+
"description": "Core validation functionality and rules for Swift applications. Contains base types, protocols, and validator implementations.",
62+
"badge": "Core Module"
63+
},
64+
{
65+
"name": "ValidatorUI",
66+
"path": "validatorui",
67+
"description": "UI components and helpers for building validation interfaces. Ready-to-use solutions for SwiftUI and UIKit.",
68+
"badge": "UI Module"
69+
}
70+
]
71+
72+
- name: Deploy
73+
uses: peaceiris/actions-gh-pages@v3
74+
with:
75+
github_token: ${{ secrets.GITHUB_TOKEN }}
76+
publish_dir: ./docs

Sources/ValidatorCore/Classes/Core/Interfaces/IValidationError.swift

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

66
import Foundation
77

8-
/// `IValidationError` is the error type returned by Validator.
8+
/// `IValidationError` is the protocol representing a validation error in `ValidatorCore`.
9+
/// Any type conforming to `IValidationError` can be returned when validation fails.
10+
///
11+
/// Example usage:
12+
/// ```swift
13+
/// struct MyError: IValidationError {
14+
/// var message: String { "Invalid input" }
15+
/// }
16+
/// ```
917
public protocol IValidationError: Error {
10-
/// The error message.
18+
/// A human-readable error message describing why validation failed.
1119
var message: String { get }
1220
}

Sources/ValidatorCore/Classes/Core/Interfaces/IValidationRule.swift

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

66
import Foundation
77

8-
/// A type that verifies the input data.
8+
/// `IValidationRule` is a generic protocol representing a validation rule.
9+
/// Types conforming to this protocol define the logic for validating input values of type `Input`.
10+
///
11+
/// You can create custom validators by implementing this protocol.
12+
///
13+
/// Example:
14+
/// ```swift
15+
/// struct NonEmptyRule: IValidationRule<String> {
16+
/// let error = "Field cannot be empty"
17+
/// func validate(input: String) -> Bool {
18+
/// !input.isEmpty
19+
/// }
20+
/// }
21+
/// ```
922
public protocol IValidationRule<Input> {
10-
/// The validation type.
23+
/// The type of input this validator works with.
1124
associatedtype Input
1225

13-
/// The validation error.
26+
/// The validation error that will be returned if validation fails.
1427
var error: IValidationError { get }
1528

16-
/// Validates an input value.
29+
/// Validates the provided input.
1730
///
18-
/// - Parameter input: The input value.
19-
///
20-
/// - Returns: A validation result.
31+
/// - Parameter input: The value to validate.
32+
/// - Returns: `true` if the input passes validation, `false` otherwise.
2133
func validate(input: Input) -> Bool
2234
}

Sources/ValidatorCore/Classes/Core/Models/ValidationResult.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55

66
import Foundation
77

8+
/// `ValidationResult` represents the outcome of a validation operation.
9+
/// It can either be `.valid` when all checks pass or `.invalid` with a list of errors.
810
public enum ValidationResult {
9-
/// Indicates that the validation was successful.
11+
/// Indicates that validation succeeded.
1012
case valid
1113

12-
/// Indicates that the validation failed with a list of errors.
14+
/// Indicates that validation failed.
1315
///
14-
/// - Parameter errors: An array of validation errors.
16+
/// - Parameter errors: An array of `IValidationError` instances describing each failure.
1517
case invalid(errors: [IValidationError])
1618
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,21 @@
66
import Foundation
77

88
#if hasFeature(RetroactiveAttribute)
9+
/// Retroactive conformance to `Error` for `String` if the feature is enabled.
910
extension String: @retroactive Error {}
1011
#endif
1112

1213
// MARK: - String + IValidationError
1314

15+
/// Makes `String` conform to `IValidationError`.
16+
/// This allows simple string literals to be used as validation errors without creating a custom type.
17+
///
18+
/// Example:
19+
/// ```swift
20+
/// let error: IValidationError = "Invalid input"
21+
/// print(error.message) // "Invalid input"
22+
/// ```
1423
extension String: IValidationError {
24+
/// Returns the string itself as the error message.
1525
public var message: String { self }
1626
}

Sources/ValidatorCore/Classes/Extensions/ValidationResult+Equatable.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,23 @@
55

66
import Foundation
77

8+
/// Adds `Equatable` conformance to `ValidationResult`.
9+
/// Validation results are considered equal if both are `.valid`
10+
/// or if both are `.invalid` and all error messages match.
11+
///
12+
/// Example:
13+
/// ```swift
14+
/// let r1: ValidationResult = .invalid(errors: ["Error 1", "Error 2"])
15+
/// let r2: ValidationResult = .invalid(errors: ["Error 1", "Error 2"])
16+
/// print(r1 == r2) // true
17+
/// ```
818
extension ValidationResult: Equatable {
919
public static func == (lhs: ValidationResult, rhs: ValidationResult) -> Bool {
1020
switch (lhs, rhs) {
1121
case (.valid, .valid):
1222
true
13-
case let (.invalid(errors: lhs), .invalid(errors: rhs)):
14-
lhs.map(\.message).joined() == rhs.map(\.message).joined()
23+
case let (.invalid(errors: lhsErrors), .invalid(errors: rhsErrors)):
24+
lhsErrors.map(\.message).joined() == rhsErrors.map(\.message).joined()
1525
default:
1626
false
1727
}

Sources/ValidatorCore/Classes/Rules/CharactersValidationRule.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,34 @@
55

66
import Foundation
77

8-
/// A characters validation rule.
8+
/// Validates that a string contains only allowed characters.
9+
///
10+
/// # Example:
11+
/// ```swift
12+
/// let rule = CharactersValidationRule(characterSet: .letters, error: "Only letters allowed")
13+
/// rule.validate(input: "Hello") // true
14+
/// rule.validate(input: "Hello123") // false
15+
/// ```
916
public struct CharactersValidationRule: IValidationRule {
1017
// MARK: Types
1118

1219
public typealias Input = String
1320

1421
// MARK: Properties
1522

23+
/// The set of allowed characters.
1624
public let characterSet: CharacterSet
1725

18-
/// The validation error.
26+
/// The validation error returned if input contains invalid characters.
1927
public let error: IValidationError
2028

2129
// MARK: Initialization
2230

31+
/// Initializes a characters validation rule.
32+
///
33+
/// - Parameters:
34+
/// - characterSet: Allowed character set.
35+
/// - error: The validation error to return if input fails validation.
2336
public init(characterSet: CharacterSet, error: IValidationError) {
2437
self.characterSet = characterSet
2538
self.error = error

Sources/ValidatorCore/Classes/Rules/CreditCardValidationRule.swift

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,50 @@
33
// Copyright © 2025 Space Code. All rights reserved.
44
//
55

6-
/// A credit card validation rule.
6+
/// Validates credit card numbers using card type prefixes and the Luhn algorithm.
7+
/// Supports Visa, MasterCard, Amex, JCB, and UnionPay.
8+
/// The validation checks both the prefix/length of the card and the Luhn checksum.
9+
///
10+
/// # Example:
11+
/// ```swift
12+
/// let rule = CreditCardValidationRule(types: [.visa, .masterCard], error: "Invalid card")
13+
/// rule.validate(input: "4111 1111 1111 1111") // true for Visa
14+
/// ```
715
public struct CreditCardValidationRule: IValidationRule {
816
// MARK: Types
917

18+
/// Represents the supported credit card types.
19+
/// Each type has specific prefix and length rules.
1020
public enum CardType: String, Sendable, CaseIterable {
11-
case visa, masterCard, amex, jcb, unionPay
21+
/// Visa cards start with 4 and have 13, 16, or 19 digits.
22+
case visa
23+
/// MasterCard cards start with 51–55 and have 16 digits.
24+
case masterCard
25+
/// American Express cards start with 34 or 37 and have 15 digits.
26+
case amex
27+
/// JCB cards start with 3528–3589 and have 16 digits.
28+
case jcb
29+
/// UnionPay cards start with 62 and have 16–19 digits.
30+
case unionPay
1231
}
1332

1433
public typealias Input = String
1534

1635
// MARK: Properties
1736

37+
/// Allowed card types for validation.
1838
public let types: [CardType]
1939

20-
/// The validation error.
40+
/// Validation error returned if the card is invalid.
2141
public let error: IValidationError
2242

2343
// MARK: Initialization
2444

45+
/// Initializes a credit card validation rule.
46+
///
47+
/// - Parameters:
48+
/// - types: The allowed card types. Defaults to all supported card types.
49+
/// - error: The validation error to return if input fails validation.
2550
public init(types: [CardType] = CardType.allCases, error: IValidationError) {
2651
self.types = types
2752
self.error = error

Sources/ValidatorCore/Classes/Rules/EmailValidationRule.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,30 @@
55

66
import Foundation
77

8-
/// An email validation rule.
8+
/// Validates that a string is a valid email address.
9+
/// Uses a regular expression conforming to RFC 5322 (simplified).
10+
///
11+
/// # Example:
12+
/// ```swift
13+
/// let rule = EmailValidationRule(error: "Invalid email")
14+
/// rule.validate(input: "user@example.com") // true
15+
/// ```
916
public struct EmailValidationRule: IValidationRule {
1017
// MARK: Types
1118

1219
public typealias Input = String
1320

1421
// MARK: Properties
1522

16-
/// The validation error.
23+
/// Validation error returned if the email is invalid.
1724
public let error: IValidationError
1825

1926
// MARK: Initialization
2027

28+
/// Initializes an email validation rule.
29+
///
30+
/// - Parameters:
31+
/// - error: The validation error to return if input fails validation.
2132
public init(error: IValidationError) {
2233
self.error = error
2334
}

Sources/ValidatorCore/Classes/Rules/LengthValidationRule.swift

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,41 @@
55

66
import Foundation
77

8-
/// A length validation rule.
8+
/// Validates that a string length is within the specified range.
9+
///
10+
/// This rule checks whether the input string's length is greater than or equal to `min`
11+
/// and less than or equal to `max`. If the string length falls outside this range, validation fails.
12+
///
13+
/// # Example:
14+
/// ```swift
15+
/// let rule = LengthValidationRule(min: 3, max: 10, error: "Length out of range")
16+
/// rule.validate(input: "Hello") // true
17+
/// rule.validate(input: "Hi") // false
18+
/// ```
919
public struct LengthValidationRule: IValidationRule {
1020
// MARK: Types
1121

1222
public typealias Input = String
1323

1424
// MARK: Properties
1525

16-
/// The minimum length.
26+
/// The minimum allowed length of the string. Defaults to `0`.
1727
public let min: Int
1828

19-
/// The maximum length.
29+
/// The maximum allowed length of the string. Defaults to `Int.max`.
2030
public let max: Int
2131

22-
/// The validation error.
32+
/// The validation error returned if the input does not satisfy the length constraints.
2333
public let error: IValidationError
2434

2535
// MARK: Initialization
2636

37+
/// Initializes a length validation rule.
38+
///
39+
/// - Parameters:
40+
/// - min: The minimum allowed string length. Defaults to 0.
41+
/// - max: The maximum allowed string length. Defaults to `Int.max`.
42+
/// - error: The validation error returned if input is invalid.
2743
public init(min: Int = .zero, max: Int = .max, error: IValidationError) {
2844
self.min = min
2945
self.max = max

0 commit comments

Comments
 (0)