@@ -9,116 +9,128 @@ import Foundation
99import SwiftUI
1010
1111public class ValidationRule {
12- public var message : String ?
12+ public var message : String
1313 public let isExternal : Bool
14+ public let conditions : [ ValidationBehaviour ]
1415
15- private let checkClosure : ( String ) async -> String ?
16+ private let checkClosure : ( String ) async -> ( Bool , String )
1617
17- internal required init ( isExternal: Bool , checkClosure: @escaping ( String ) async -> String ? ) {
18+ internal required init (
19+ conditions: [ ValidationBehaviour ] ,
20+ isExternal: Bool ,
21+ checkClosure: @escaping ( String ) async -> ( Bool , String )
22+ ) {
23+ self . message = . empty
1824 self . checkClosure = checkClosure
1925 self . isExternal = isExternal
26+ self . conditions = conditions
2027 }
2128
2229 public func check( value: String ) async -> Bool {
23- let message = await checkClosure ( value)
30+ let ( result , message) = await checkClosure ( value)
2431 self . message = message
2532
26- return message == nil
33+ return result
2734 }
2835}
2936
3037extension ValidationRule {
31- public static func custom( checkClosure: @escaping ( String ) async -> String ? ) -> Self {
32- return Self ( isExternal: false , checkClosure: checkClosure)
38+ public static func custom(
39+ conditions: [ ValidationBehaviour ] ,
40+ checkClosure: @escaping ( String ) async -> ( Bool , String )
41+ ) -> Self {
42+ return Self ( conditions: conditions, isExternal: false , checkClosure: checkClosure)
3343 }
3444
35- public static func external( checkClosure: @escaping ( String ) async -> String ? ) -> Self {
36- return Self ( isExternal: true , checkClosure: checkClosure)
45+ public static func external( checkClosure: @escaping ( String ) async -> ( Bool , String ) ) -> Self {
46+ return Self ( conditions : [ . manual ] , isExternal: true , checkClosure: checkClosure)
3747 }
3848
39- public static func notEmpty( message: String ) -> Self {
40- return Self ( isExternal: false ) {
41- return $0. isEmpty == false ? nil : message
49+ public static func notEmpty( conditions : [ ValidationBehaviour ] , message: String ) -> Self {
50+ return Self ( conditions : conditions , isExternal: false ) {
51+ return ( $0. isEmpty == false , message)
4252 }
4353 }
4454
45- public static func atLeastOneLowercaseLetter( message: String ) -> Self {
46- return Self ( isExternal: false ) {
47- return $0. rangeOfCharacter ( from: CharacterSet . lowercaseLetters) != nil ? nil : message
55+ public static func atLeastOneLowercaseLetter( conditions : [ ValidationBehaviour ] , message: String ) -> Self {
56+ return Self ( conditions : conditions , isExternal: false ) {
57+ return ( $0. rangeOfCharacter ( from: CharacterSet . lowercaseLetters) != nil , message)
4858 }
4959 }
5060
51- public static func atLeastOneUppercaseLetter( message: String ) -> Self {
52- return Self ( isExternal: false ) {
53- $0. rangeOfCharacter ( from: CharacterSet . uppercaseLetters) != nil ? nil : message
61+ public static func atLeastOneUppercaseLetter( conditions : [ ValidationBehaviour ] , message: String ) -> Self {
62+ return Self ( conditions : conditions , isExternal: false ) {
63+ return ( $0. rangeOfCharacter ( from: CharacterSet . uppercaseLetters) != nil , message)
5464 }
5565 }
5666
57- public static func atLeastOneDigit( message: String ) -> Self {
58- return Self ( isExternal: false ) {
59- $0. rangeOfCharacter ( from: CharacterSet . decimalDigits) != nil ? nil : message
67+ public static func atLeastOneDigit( conditions : [ ValidationBehaviour ] , message: String ) -> Self {
68+ return Self ( conditions : conditions , isExternal: false ) {
69+ return ( $0. rangeOfCharacter ( from: CharacterSet . decimalDigits) != nil , message)
6070 }
6171 }
6272
63- public static func atLeastOneLetter( message: String ) -> Self {
64- return Self ( isExternal: false ) {
65- $0. rangeOfCharacter ( from: CharacterSet . letters) != nil ? nil : message
73+ public static func atLeastOneLetter( conditions : [ ValidationBehaviour ] , message: String ) -> Self {
74+ return Self ( conditions : conditions , isExternal: false ) {
75+ return ( $0. rangeOfCharacter ( from: CharacterSet . letters) != nil , message)
6676 }
6777 }
6878
69- public static func digitsOnly( message: String ) -> Self {
70- return Self ( isExternal: false ) {
71- CharacterSet . decimalDigits. isSuperset ( of: CharacterSet ( charactersIn: $0) ) ? nil : message
79+ public static func digitsOnly( conditions : [ ValidationBehaviour ] , message: String ) -> Self {
80+ return Self ( conditions : conditions , isExternal: false ) {
81+ return ( CharacterSet . decimalDigits. isSuperset ( of: CharacterSet ( charactersIn: $0) ) , message)
7282 }
7383 }
7484
75- public static func lettersOnly( message: String ) -> Self {
76- return Self ( isExternal: false ) {
77- CharacterSet . letters. isSuperset ( of: CharacterSet ( charactersIn: $0) ) ? nil : message
85+ public static func lettersOnly( conditions : [ ValidationBehaviour ] , message: String ) -> Self {
86+ return Self ( conditions : conditions , isExternal: false ) {
87+ return ( CharacterSet . letters. isSuperset ( of: CharacterSet ( charactersIn: $0) ) , message)
7888 }
7989 }
8090
81- public static func atLeastOneSpecialCharacter( message: String ) -> Self {
82- return Self ( isExternal: false ) {
83- $0. range ( of: " .*[^A-Za-zА-Яа-яё0-9 ].* " , options: . regularExpression) != nil ? nil : message
91+ public static func atLeastOneSpecialCharacter( conditions : [ ValidationBehaviour ] , message: String ) -> Self {
92+ return Self ( conditions : conditions , isExternal: false ) {
93+ return ( $0. range ( of: " .*[^A-Za-zА-Яа-яё0-9 ].* " , options: . regularExpression) != nil , message)
8494 }
8595 }
8696
87- public static func noSpecialCharacters( message: String ) -> Self {
88- return Self ( isExternal: false ) {
89- $0. range ( of: " .*[^A-Za-zА-Яа-яё0-9 ].* " , options: . regularExpression) == nil ? nil : message
97+ public static func noSpecialCharacters( conditions : [ ValidationBehaviour ] , message: String ) -> Self {
98+ return Self ( conditions : conditions , isExternal: false ) {
99+ return ( $0. range ( of: " .*[^A-Za-zА-Яа-яё0-9 ].* " , options: . regularExpression) == nil , message)
90100 }
91101 }
92102
93- public static func email( message: String ) -> Self {
94- return Self ( isExternal: false ) {
95- NSPredicate ( format: " SELF MATCHES %@ " , " [A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+ \\ .[A-Za-z]{2,} " )
96- . evaluate ( with: $0) ? nil : message
103+ public static func email( conditions: [ ValidationBehaviour ] , message: String ) -> Self {
104+ return Self ( conditions: conditions, isExternal: false ) {
105+ return (
106+ NSPredicate ( format: " SELF MATCHES %@ " , " [A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+ \\ .[A-Za-z]{2,} " )
107+ . evaluate ( with: $0) ,
108+ message
109+ )
97110 }
98111 }
99112
100- public static func notRecurringPincode( message: String ) -> Self {
101- return Self ( isExternal: false ) {
102- $0. range ( of: " ([0-9]) \\ 1 \\ 1 \\ 1 " , options: . regularExpression) == nil ? nil : message
113+ public static func notRecurringPincode( conditions : [ ValidationBehaviour ] , message: String ) -> Self {
114+ return Self ( conditions : conditions , isExternal: false ) {
115+ return ( $0. range ( of: " ([0-9]) \\ 1 \\ 1 \\ 1 " , options: . regularExpression) == nil , message)
103116 }
104117 }
105118
106- public static func minLength( count: Int , message: String ) -> Self {
107- return Self ( isExternal: false ) {
108- $0. count >= count ? nil : message
119+ public static func minLength( conditions : [ ValidationBehaviour ] , count: Int , message: String ) -> Self {
120+ return Self ( conditions : conditions , isExternal: false ) {
121+ return ( $0. count >= count, message)
109122 }
110123 }
111124
112- public static func maxLength( count: Int , message: String ) -> Self {
113- return Self ( isExternal: false ) {
114- $0. count <= count ? nil : message
125+ public static func maxLength( conditions : [ ValidationBehaviour ] , count: Int , message: String ) -> Self {
126+ return Self ( conditions : conditions , isExternal: false ) {
127+ return ( $0. count <= count, message)
115128 }
116129 }
117130
118- public static func regex( value: String , message: String ) -> Self {
119- return Self ( isExternal: false ) {
120- NSPredicate ( format: " SELF MATCHES %@ " , value)
121- . evaluate ( with: $0) ? nil : message
131+ public static func regex( conditions: [ ValidationBehaviour ] , value: String , message: String ) -> Self {
132+ return Self ( conditions: conditions, isExternal: false ) {
133+ return ( NSPredicate ( format: " SELF MATCHES %@ " , value) . evaluate ( with: $0) , message)
122134 }
123135 }
124136}
0 commit comments