github.com/m4gshm/gollections@v0.0.13-0.20240331203319-a34a86e58a24/predicate/api.go (about) 1 // Package predicate provides predicate builders 2 package predicate 3 4 import ( 5 "github.com/m4gshm/gollections/slice" 6 ) 7 8 // Predicate tests value (converts to true or false). 9 type Predicate[T any] func(T) bool 10 11 // Or makes disjunction 12 func (p Predicate[T]) Or(or Predicate[T]) Predicate[T] { return Or(p, or) } 13 14 // And makes conjunction 15 func (p Predicate[T]) And(and Predicate[T]) Predicate[T] { return And(p, and) } 16 17 // Xor makes exclusive OR 18 func (p Predicate[T]) Xor(xor Predicate[T]) Predicate[T] { return Xor(p, xor) } 19 20 // Eq creates a predicate to test for equality 21 func Eq[T comparable](v T) Predicate[T] { 22 return func(c T) bool { return v == c } 23 } 24 25 // Not negates the 'p' predicate 26 func Not[T any](p Predicate[T]) Predicate[T] { 27 return func(v T) bool { return !p(v) } 28 } 29 30 // And makes a conjunction of two predicates 31 func And[T any](p1, p2 Predicate[T]) Predicate[T] { 32 return func(v T) bool { return p1(v) && p2(v) } 33 } 34 35 // Or makes a disjunction of two predicates 36 func Or[T any](p1, p2 Predicate[T]) Predicate[T] { 37 return func(v T) bool { return p1(v) || p2(v) } 38 } 39 40 // Xor makes an exclusive OR of two predicates 41 func Xor[T any](p1, p2 Predicate[T]) Predicate[T] { 42 return func(v T) bool { return !(p1(v) == p2(v)) } 43 } 44 45 // Union applies And to predicates 46 func Union[T any](predicates ...Predicate[T]) Predicate[T] { 47 l := len(predicates) 48 if l == 0 { 49 return func(_ T) bool { return false } 50 } else if l == 1 { 51 return predicates[0] 52 } else if l == 2 { 53 return And(predicates[0], predicates[1]) 54 } 55 return func(v T) bool { 56 for i := 0; i < len(predicates); i++ { 57 if !predicates[i](v) { 58 return false 59 } 60 } 61 return true 62 } 63 } 64 65 // Match creates a predicate that tests whether a value of a structure property matches a specified condition 66 func Match[Entity, Property any](getter func(Entity) Property, condition Predicate[Property]) Predicate[Entity] { 67 return func(entity Entity) bool { return condition(getter(entity)) } 68 } 69 70 // MatchAny creates a predicate that tests whether any value of a structure property matches a specified condition 71 // The property has a slice type. 72 func MatchAny[Entity, Property any](getter func(Entity) []Property, condition Predicate[Property]) Predicate[Entity] { 73 return func(entity Entity) bool { 74 return slice.Has(getter(entity), condition) 75 } 76 }