Crate predicates

source ·
Expand description

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 = "1.0.7"

A prelude is available to bring in all extension traits as well as providing prelude::predicate which focuses on the 90% case of the API.

use predicates::prelude::*;

Examples

The simplest predicates are predicate::always and predicate::never, which always returns true and always returns false, respectively. The values are simply ignored when evaluating against these predicates:

use predicates::prelude::*;

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.

use predicates::prelude::*;

let less_than_ten = predicate::lt(10);
assert_eq!(true, less_than_ten.eval(&9));
assert_eq!(false, less_than_ten.eval(&11));

Any function over a reference to the desired Item that returns bool can easily be made into a Predicate using the predicate::function function.

use predicates::prelude::*;

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));

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:

use predicates::prelude::*;

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!

use std::fmt;

use predicates::prelude::*;

struct IsTheAnswer;
impl Predicate<i32> for IsTheAnswer {
    fn eval(&self, variable: &i32) -> bool {
        *variable == 42
    }
}
impl predicates::reflection::PredicateReflection for IsTheAnswer {}
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));

Choosing a Predicate

General predicates

Combinators

String predicates

File system predicates

Modules

Definition of boolean logic combinators over Predicates.
Definition of a constant (always true or always false) Predicate.
Float Predicates
Definition of Predicate for wrapping a Fn(&T) -> bool
Definition of Predicates for comparisons of membership in a set.
Name predicate expressions.
Definition of Predicates for comparisons over Ord and Eq types.
Path Predicates
Module that contains the essentials for working with predicates.
Introspect into the state of a Predicate.
String Predicates

Structs

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

Traits

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