Skip to content

Commit bdc9ebd

Browse files
committed
Compute a compound result optimally
1 parent 01c0fb8 commit bdc9ebd

File tree

4 files changed

+45
-28
lines changed

4 files changed

+45
-28
lines changed

Example/FormHookExample/ContentView.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ struct ContentView: HookView {
153153
picker
154154
Text(error)
155155
.font(.system(size: 10)).foregroundColor(.red)
156-
.font(.system(size: 10)).foregroundColor(.red)
157156
}
158157
} else {
159158
picker

Sources/FormHook/Form.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ public struct ContextualForm<Content, FieldName>: View where Content: View, Fiel
548548
shouldUnregister: Bool = true,
549549
shouldFocusError: Bool = true,
550550
delayErrorInNanoseconds: UInt64 = 0,
551-
onFocusedField: @escaping (FieldName) -> Void,
551+
@_implicitSelfCapture onFocusedField: @escaping (FieldName) -> Void,
552552
@ViewBuilder content: @escaping (FormControl<FieldName>) -> Content
553553
) {
554554
self.formOptions = .init(

Sources/FormHook/Hook/UseForm.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public func useForm<FieldName>(
1717
shouldUnregister: Bool = true,
1818
shouldFocusError: Bool,
1919
delayErrorInNanoseconds: UInt64 = 0,
20-
onFocusedField: @escaping (FieldName) -> Void
20+
@_implicitSelfCapture onFocusedField: @escaping (FieldName) -> Void
2121
) -> FormControl<FieldName> where FieldName: Hashable {
2222
useForm(
2323
FormOption(

Sources/FormHook/Validation/CompoundValidator.swift

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,61 +48,79 @@ private struct CompoundValidator<Value>: Validator {
4848
}
4949

5050
func validate(_ value: Value) async -> CompountValidationResult {
51-
let pairs = await withTaskGroup(of: ValidatorResultPair.self) { group in
51+
await withTaskGroup(of: ValidatorResultPair.self) { group in
5252
validators.forEach { validator in
5353
group.addTask {
5454
let result = await validator.validate(value)
5555
return (validator, result)
5656
}
5757
}
58-
var results: [ValidatorResultPair] = []
5958
if shouldGetAllMessages {
60-
for await resultPair in group {
61-
results.append(resultPair)
59+
var isValid: Bool
60+
var results: [ValidatorResultPair] = []
61+
switch `operator` {
62+
case .and:
63+
isValid = true
64+
for await resultPair in group {
65+
results.append(resultPair)
66+
if !resultPair.0.isValid(result: resultPair.1) {
67+
isValid = false
68+
}
69+
}
70+
case .or:
71+
isValid = false
72+
for await resultPair in group {
73+
results.append(resultPair)
74+
if resultPair.0.isValid(result: resultPair.1) {
75+
isValid = true
76+
}
77+
}
6278
}
63-
return results
79+
return CompountValidationResult(
80+
messages: results.flatMap { (validator, result) in validator.generateMessage(result: result) },
81+
boolValue: isValid
82+
)
6483
}
84+
var results: [ValidatorResultPair] = []
6585
switch `operator` {
6686
case .and:
6787
for await resultPair in group {
6888
results.append(resultPair)
6989
guard resultPair.0.isValid(result: resultPair.1) else {
70-
return results
90+
return CompountValidationResult(
91+
messages: results.flatMap { (validator, result) in validator.generateMessage(result: result) },
92+
boolValue: false
93+
)
7194
}
7295
}
73-
return results
96+
return CompountValidationResult(
97+
messages: results.flatMap { (validator, result) in validator.generateMessage(result: result) },
98+
boolValue: true
99+
)
74100
case .or:
75101
for await resultPair in group {
76102
results.append(resultPair)
77103
if resultPair.0.isValid(result: resultPair.1) {
78-
return results
104+
return CompountValidationResult(
105+
messages: results.flatMap { (validator, result) in validator.generateMessage(result: result) },
106+
boolValue: true
107+
)
79108
}
80109
}
81-
return results
110+
return CompountValidationResult(
111+
messages: results.flatMap { (validator, result) in validator.generateMessage(result: result) },
112+
boolValue: false
113+
)
82114
}
83115
}
84-
return CompountValidationResult(pairs: pairs, operator: self.operator)
85116
}
86117
}
87118

88119
private typealias ValidatorResultPair = (AnyValidator, Any)
89120

90121
private struct CompountValidationResult: BoolConvertible, MessageGenerator {
91-
let pairs: [ValidatorResultPair]
92-
let `operator`: CompoundValidatorOperator
93-
94-
var boolValue: Bool {
95-
switch `operator` {
96-
case .and:
97-
return !pairs.contains { validator, result in !validator.isValid(result: result) }
98-
case .or:
99-
return pairs.contains { validator, result in validator.isValid(result: result) }
100-
}
101-
}
102-
103-
var messages: [String] {
104-
pairs.flatMap { validator, result in validator.generateMessage(result: result) }
105-
}
122+
let messages: [String]
123+
let boolValue: Bool
106124
}
107125

108126
private struct PreMapValidator<Value, Result, Output>: Validator {

0 commit comments

Comments
 (0)