Skip to content

Commit

Permalink
feat: Add basic reflection
Browse files Browse the repository at this point in the history
Predicates can now report parameter details that don't show up in
`Display` as well as what children they have.  The expectation is that
this will be used by the solution for assert-rs#7.

BREAKING CHANGE: `Predicate`s must also implement
`reflection::PredicateReflection`.
  • Loading branch information
epage committed Jul 20, 2018
1 parent 5dbc1a1 commit fc099fb
Show file tree
Hide file tree
Showing 19 changed files with 237 additions and 4 deletions.
24 changes: 24 additions & 0 deletions src/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use std::fmt;
use std::marker::PhantomData;

use reflection;
use Predicate;

/// Predicate that combines two `Predicate`s, returning the AND of the results.
Expand Down Expand Up @@ -55,6 +56,14 @@ where
}
}

impl<M1, M2, Item> reflection::PredicateReflection for AndPredicate<M1, M2, Item>
where
M1: Predicate<Item>,
M2: Predicate<Item>,
Item: ?Sized,
{
}

impl<M1, M2, Item> fmt::Display for AndPredicate<M1, M2, Item>
where
M1: Predicate<Item>,
Expand Down Expand Up @@ -108,6 +117,14 @@ where
}
}

impl<M1, M2, Item> reflection::PredicateReflection for OrPredicate<M1, M2, Item>
where
M1: Predicate<Item>,
M2: Predicate<Item>,
Item: ?Sized,
{
}

impl<M1, M2, Item> fmt::Display for OrPredicate<M1, M2, Item>
where
M1: Predicate<Item>,
Expand Down Expand Up @@ -156,6 +173,13 @@ where
}
}

impl<M, Item> reflection::PredicateReflection for NotPredicate<M, Item>
where
M: Predicate<Item>,
Item: ?Sized,
{
}

impl<M, Item> fmt::Display for NotPredicate<M, Item>
where
M: Predicate<Item>,
Expand Down
7 changes: 7 additions & 0 deletions src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use std::fmt;

use reflection;
use Predicate;

/// `Predicate` that wraps another `Predicate` as a trait object, allowing
Expand Down Expand Up @@ -40,6 +41,12 @@ where
}
}

impl<Item> reflection::PredicateReflection for BoxPredicate<Item>
where
Item: ?Sized,
{
}

impl<Item> fmt::Display for BoxPredicate<Item>
where
Item: ?Sized,
Expand Down
3 changes: 3 additions & 0 deletions src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use std::fmt;
use std::marker::PhantomData;

use reflection;
use Predicate;

/// Predicate that always returns a constant (boolean) result.
Expand All @@ -28,6 +29,8 @@ impl<Item> Predicate<Item> for BooleanPredicate<Item> {
}
}

impl<Item> reflection::PredicateReflection for BooleanPredicate<Item> {}

impl<Item> fmt::Display for BooleanPredicate<Item> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.retval)
Expand Down
4 changes: 2 additions & 2 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;
use reflection;

/// Trait for generically evaluating a type against a dynamically created
/// predicate function.
Expand All @@ -15,7 +15,7 @@ use std::fmt;
/// mean that the evaluated item is in some sort of pre-defined set. This is
/// different from `Ord` and `Eq` in that an `item` will almost never be the
/// same type as the implementing `Predicate` type.
pub trait Predicate<Item: ?Sized>: fmt::Display {
pub trait Predicate<Item: ?Sized>: reflection::PredicateReflection {
/// Execute this `Predicate` against `variable`, returning the resulting
/// boolean.
fn eval(&self, variable: &Item) -> bool;
Expand Down
3 changes: 3 additions & 0 deletions src/float/close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::fmt;
use float_cmp::ApproxEq;
use float_cmp::Ulps;

use reflection;
use Predicate;

/// Predicate that ensures two numbers are "close" enough, understanding that rounding errors
Expand Down Expand Up @@ -86,6 +87,8 @@ impl Predicate<f64> for IsClosePredicate {
}
}

impl reflection::PredicateReflection for IsClosePredicate {}

impl fmt::Display for IsClosePredicate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
Expand Down
7 changes: 7 additions & 0 deletions src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use std::fmt;
use std::marker::PhantomData;

use reflection;
use Predicate;

/// Predicate that wraps a function over a reference that returns a `bool`.
Expand Down Expand Up @@ -60,6 +61,12 @@ where
}
}

impl<F, T> reflection::PredicateReflection for FnPredicate<F, T>
where
F: Fn(&T) -> bool,
{
}

impl<F, T> fmt::Display for FnPredicate<F, T>
where
F: Fn(&T) -> bool,
Expand Down
19 changes: 19 additions & 0 deletions src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::fmt;
use std::hash::Hash;
use std::iter::FromIterator;

use reflection;
use Predicate;

/// Predicate that returns `true` if `variable` is a member of the pre-defined
Expand Down Expand Up @@ -84,6 +85,12 @@ where
}
}

impl<T> reflection::PredicateReflection for InPredicate<T>
where
T: PartialEq + fmt::Debug,
{
}

impl<T> fmt::Display for InPredicate<T>
where
T: PartialEq + fmt::Debug,
Expand Down Expand Up @@ -167,6 +174,12 @@ where
}
}

impl<T> reflection::PredicateReflection for OrdInPredicate<T>
where
T: Ord + fmt::Debug,
{
}

impl<T> fmt::Display for OrdInPredicate<T>
where
T: Ord + fmt::Debug,
Expand Down Expand Up @@ -211,6 +224,12 @@ where
}
}

impl<T> reflection::PredicateReflection for HashableInPredicate<T>
where
T: Hash + Eq + fmt::Debug,
{
}

impl<T> fmt::Display for HashableInPredicate<T>
where
T: Hash + Eq + fmt::Debug,
Expand Down
6 changes: 4 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
//! *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()")
Expand Down Expand Up @@ -101,9 +102,10 @@ extern crate regex;
pub mod prelude;

mod core;
pub use core::Predicate;
pub use core::*;
mod boxed;
pub use boxed::BoxPredicate;
pub use boxed::*;
pub mod reflection;

// core predicates
pub mod constant;
Expand Down
8 changes: 8 additions & 0 deletions src/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use std::fmt;
use std::marker::PhantomData;

use reflection;
use Predicate;

/// Augment an existing predicate with a name.
Expand All @@ -37,6 +38,13 @@ where
}
}

impl<M, Item> reflection::PredicateReflection for NamePredicate<M, Item>
where
M: Predicate<Item>,
Item: ?Sized,
{
}

impl<M, Item> fmt::Display for NamePredicate<M, Item>
where
M: Predicate<Item>,
Expand Down
13 changes: 13 additions & 0 deletions src/ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use std::fmt;

use reflection;
use Predicate;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -65,6 +66,12 @@ where
}
}

impl<T> reflection::PredicateReflection for EqPredicate<T>
where
T: fmt::Debug + PartialEq,
{
}

impl<T> fmt::Display for EqPredicate<T>
where
T: fmt::Debug + PartialEq,
Expand Down Expand Up @@ -183,6 +190,12 @@ where
}
}

impl<T> reflection::PredicateReflection for OrdPredicate<T>
where
T: fmt::Debug + PartialOrd,
{
}

impl<T> fmt::Display for OrdPredicate<T>
where
T: fmt::Debug + PartialOrd,
Expand Down
3 changes: 3 additions & 0 deletions src/path/existence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use std::fmt;
use std::path;

use reflection;
use Predicate;

/// Predicate that checks if a file is present
Expand All @@ -25,6 +26,8 @@ impl Predicate<path::Path> for ExistencePredicate {
}
}

impl reflection::PredicateReflection for ExistencePredicate {}

impl fmt::Display for ExistencePredicate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}(var)", if self.exists { "exists" } else { "missing" })
Expand Down
7 changes: 7 additions & 0 deletions src/path/fc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::fs;
use std::io::{self, Read};
use std::path;

use reflection;
use Predicate;

fn read_file(path: &path::Path) -> io::Result<Vec<u8>> {
Expand Down Expand Up @@ -40,6 +41,12 @@ where
}
}

impl<P> reflection::PredicateReflection for FileContentPredicate<P>
where
P: Predicate<[u8]>,
{
}

impl<P> fmt::Display for FileContentPredicate<P>
where
P: Predicate<[u8]>,
Expand Down
5 changes: 5 additions & 0 deletions src/path/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::fs;
use std::io::{self, Read};
use std::path;

use reflection;
use Predicate;

fn read_file(path: &path::Path) -> io::Result<Vec<u8>> {
Expand Down Expand Up @@ -66,6 +67,8 @@ impl Predicate<[u8]> for BinaryFilePredicate {
}
}

impl reflection::PredicateReflection for BinaryFilePredicate {}

impl fmt::Display for BinaryFilePredicate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "var is {}", self.path.display())
Expand Down Expand Up @@ -120,6 +123,8 @@ impl Predicate<str> for StrFilePredicate {
}
}

impl reflection::PredicateReflection for StrFilePredicate {}

impl fmt::Display for StrFilePredicate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "var is {}", self.path.display())
Expand Down
3 changes: 3 additions & 0 deletions src/path/ft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::fs;
use std::io;
use std::path;

use reflection;
use Predicate;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -94,6 +95,8 @@ impl Predicate<path::Path> for FileTypePredicate {
}
}

impl reflection::PredicateReflection for FileTypePredicate {}

impl fmt::Display for FileTypePredicate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "var is {}", self.ft)
Expand Down
Loading

0 comments on commit fc099fb

Please sign in to comment.