Created
November 23, 2022 15:46
-
-
Save tpgmeligmeyling/84a62582d1930888de665d2f0be125d1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol ComparisonPredicateValue { | |
var value: Bool? { get } | |
} | |
enum ComparisonPredicate<T: Comparable>: ComparisonPredicateValue { | |
typealias Predicate = ((T, T) -> Bool) | |
case predicate(lhs: T, rhs: T, Predicate) | |
var value: Bool? { | |
switch self { | |
case .predicate(let lhs, let rhs, let predicate): | |
if !predicate(lhs, rhs) && !predicate(rhs, lhs) { | |
return nil | |
} | |
return predicate(lhs, rhs) | |
} | |
} | |
} | |
struct ComparisonBuilder { | |
let predicates: [ComparisonPredicateValue] | |
init(predicates: [ComparisonPredicateValue]) { | |
self.predicates = predicates | |
} | |
init() { | |
self.init(predicates: []) | |
} | |
private func addPredicate<T>(predicate: ComparisonPredicate<T>) -> ComparisonBuilder { | |
return ComparisonBuilder(predicates: predicates + [predicate]) | |
} | |
var value: Bool { | |
return predicates.reduce(nil) { | |
result, predicate in | |
guard result == nil else { return result } | |
return predicate.value | |
} == true | |
} | |
} | |
extension ComparisonBuilder { | |
func addPredicate<T: Comparable>(lhs: T, rhs: T, _ predicate: @escaping ComparisonPredicate<T>.Predicate) -> ComparisonBuilder { | |
let predicate = ComparisonPredicate.predicate(lhs: lhs, rhs: rhs, predicate) | |
return ComparisonBuilder(predicates: predicates + [predicate]) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment