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  }