1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
// Copyright (c) 2017, Nick Stevens <nick@bitcurry.com> // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/license/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! 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`: //! //! ```toml //! [dependencies] //! predicates = "0.2" //! ``` //! //! ## Examples //! //! A few different examples of how predicates might be used: //! //! ``` //! use predicates::{predicate, Predicate}; //! //! // 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, requiring only the //! // 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 for IsTheAnswer { //! type Item = i32; //! fn eval(&self, variable: &Self::Item) -> bool { //! *variable == 42 //! } //! } //! //! assert_eq!(true, IsTheAnswer.eval(&42)); //! let almost_the_answer = IsTheAnswer.or(predicate::contains(vec![41, 43])); //! assert_eq!(true, almost_the_answer.eval(&41)); //! ``` #![deny(missing_docs, missing_debug_implementations)] // core `Predicate` trait pub mod predicate; pub use self::predicate::Predicate;