Skip to content

Instantly share code, notes, and snippets.

@tpgmeligmeyling
Created November 23, 2022 15:46
Show Gist options
  • Save tpgmeligmeyling/84a62582d1930888de665d2f0be125d1 to your computer and use it in GitHub Desktop.
Save tpgmeligmeyling/84a62582d1930888de665d2f0be125d1 to your computer and use it in GitHub Desktop.
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