-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathJSONValidationRule.swift
More file actions
71 lines (54 loc) · 1.79 KB
/
JSONValidationRule.swift
File metadata and controls
71 lines (54 loc) · 1.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//
// Validator
// Copyright © 2026 Space Code. All rights reserved.
//
import Foundation
/// Validates that a string represents valid JSON.
///
/// # Example:
/// ```swift
/// let rule = JSONValidationRule(error: "Invalid JSON")
/// rule.validate(input: "{\"key\": \"value\"}") // true
/// rule.validate(input: "not json") // false
/// ```
public struct JSONValidationRule: IValidationRule {
// MARK: Types
public typealias Input = String
// MARK: Properties
/// The validation error returned if the input is not valid JSON.
public let error: IValidationError
// MARK: Initialization
/// Initializes a JSON validation rule.
///
/// - Parameter error: The validation error returned if input fails validation.
public init(error: IValidationError) {
self.error = error
}
// MARK: IValidationRule
public func validate(input: String) -> Bool {
guard !input.isEmpty else { return false }
guard let data = input.data(using: .utf8) else { return false }
do {
_ = try JSONSerialization.jsonObject(with: data, options: [])
} catch {
return false
}
return isStrictJSON(input)
}
// MARK: Private Methods
/// Validates strict JSON syntax to catch issues like trailing commas.
private func isStrictJSON(_ input: String) -> Bool {
let trimmed = input.trimmingCharacters(in: .whitespacesAndNewlines)
let trailingCommaPatterns = [
",\\s*}",
",\\s*\\]",
]
for pattern in trailingCommaPatterns where trimmed.range(of: pattern, options: .regularExpression) != nil {
return false
}
if trimmed.range(of: ",,", options: .literal) != nil {
return false
}
return true
}
}