Crate predicates[][src]

Composable first-order predicate functions.

This library implements an interface to "predicates" - boolean-valued functions of one argument. This allows combinatorial logic to be created and assembled at runtime and then used one or more times for evaluating values. This sort of object is really useful when creating filters and checks that can be changed at runtime with user interaction - it allows a clean separation of concerns where the configuration code can be used to build up a predicate, and then that predicate can be given to the code that does the actual filtering without the filtering code knowing anything about user configuration. See the examples for how this can work.

Installation

Add this to your Cargo.toml:

[dependencies]
predicates = "0.5"

Examples

A few different examples of how predicates might be used:

use predicates::prelude::*;

use std::fmt;

// The simplest predicates are `always()` and `never()`, which always returns
// `true` and always returns `false`, respectively. The values are simply
// ignored when evaluating against these predicates:
let always_true = predicate::always();
assert_eq!(true, always_true.eval(&5));
let always_false = predicate::never();
assert_eq!(false, always_false.eval(&5));

// Pre-made predicates are available for types that implement the `PartialOrd` and
// `PartialEq` traits. The following example uses `lt`, but `eq`, `ne`, `le`, `gt`,
// `ge` are also available.
let less_than_ten = predicate::lt(10);
assert_eq!(true, less_than_ten.eval(&9));
assert_eq!(false, less_than_ten.eval(&11));

// The `Predicate` type is actually a trait, and that trait implements a
// number of useful combinator functions. For example, evaluating for a value
// between two other values can be accomplished as follows:
let between_5_and_10 = predicate::ge(5).and(predicate::le(10));
assert_eq!(true, between_5_and_10.eval(&7));
assert_eq!(false, between_5_and_10.eval(&11));
assert_eq!(false, between_5_and_10.eval(&4));

// The `Predicate` trait is pretty simple, the core of it is an
// implementation of a `eval` function that takes a single argument and
// returns a `bool`. Implementing a custom `Predicate` still allows all the
// usual combinators of the `Predicate` trait to work!
struct IsTheAnswer;
impl Predicate<i32> for IsTheAnswer {
    fn eval(&self, variable: &i32) -> bool {
        *variable == 42
    }
}
impl fmt::Display for IsTheAnswer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "var.is_the_answer()")
    }
}

assert_eq!(true, IsTheAnswer.eval(&42));
let almost_the_answer = IsTheAnswer.or(predicate::in_iter(vec![41, 43]));
assert_eq!(true, almost_the_answer.eval(&41));

// Any function over a reference to the desired `Item` that returns `bool`
// can easily be made into a `Predicate` using the `predicate::function`
// function.
let bound = 5;
let predicate_fn = predicate::function(|&x| x >= bound);
let between_5_and_10 = predicate_fn.and(predicate::le(10));
assert_eq!(true, between_5_and_10.eval(&7));
assert_eq!(false, between_5_and_10.eval(&3));

Modules

boolean

Definition of boolean logic combinators over Predicates.

constant

Definition of a constant (always true or always false) Predicate.

float

Float Predicates

function

Definition of Predicate for wrapping a Fn(&T) -> bool

iter

Definition of Predicates for comparisons of membership in a set.

name

Name predicate expressions.

ord

Definition of Predicates for comparisons over Ord and Eq types.

path

Path Predicates

prelude

Module that contains the essentials for working with predicates.

str

String Predicates

Structs

BoxPredicate

Predicate that wraps another Predicate as a trait object, allowing sized storage of predicate types.

Traits

Predicate

Trait for generically evaluating a type against a dynamically created predicate function.