Skip to content

Commit 5a6bf6b

Browse files
committed
feat: Add basic reflection
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 #7. BREAKING CHANGE: `Predicate`s must also implement `reflection::PredicateReflection`.
1 parent 3dcff14 commit 5a6bf6b

19 files changed

+237
-4
lines changed

src/boolean.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use std::fmt;
1212
use std::marker::PhantomData;
1313

14+
use reflection;
1415
use Predicate;
1516

1617
/// Predicate that combines two `Predicate`s, returning the AND of the results.
@@ -55,6 +56,14 @@ where
5556
}
5657
}
5758

59+
impl<M1, M2, Item> reflection::PredicateReflection for AndPredicate<M1, M2, Item>
60+
where
61+
M1: Predicate<Item>,
62+
M2: Predicate<Item>,
63+
Item: ?Sized,
64+
{
65+
}
66+
5867
impl<M1, M2, Item> fmt::Display for AndPredicate<M1, M2, Item>
5968
where
6069
M1: Predicate<Item>,
@@ -108,6 +117,14 @@ where
108117
}
109118
}
110119

120+
impl<M1, M2, Item> reflection::PredicateReflection for OrPredicate<M1, M2, Item>
121+
where
122+
M1: Predicate<Item>,
123+
M2: Predicate<Item>,
124+
Item: ?Sized,
125+
{
126+
}
127+
111128
impl<M1, M2, Item> fmt::Display for OrPredicate<M1, M2, Item>
112129
where
113130
M1: Predicate<Item>,
@@ -156,6 +173,13 @@ where
156173
}
157174
}
158175

176+
impl<M, Item> reflection::PredicateReflection for NotPredicate<M, Item>
177+
where
178+
M: Predicate<Item>,
179+
Item: ?Sized,
180+
{
181+
}
182+
159183
impl<M, Item> fmt::Display for NotPredicate<M, Item>
160184
where
161185
M: Predicate<Item>,

src/boxed.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
1212
use std::fmt;
1313

14+
use reflection;
1415
use Predicate;
1516

1617
/// `Predicate` that wraps another `Predicate` as a trait object, allowing
@@ -40,6 +41,12 @@ where
4041
}
4142
}
4243

44+
impl<Item> reflection::PredicateReflection for BoxPredicate<Item>
45+
where
46+
Item: ?Sized,
47+
{
48+
}
49+
4350
impl<Item> fmt::Display for BoxPredicate<Item>
4451
where
4552
Item: ?Sized,

src/constant.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use std::fmt;
1212
use std::marker::PhantomData;
1313

14+
use reflection;
1415
use Predicate;
1516

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

32+
impl<Item> reflection::PredicateReflection for BooleanPredicate<Item> {}
33+
3134
impl<Item> fmt::Display for BooleanPredicate<Item> {
3235
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3336
write!(f, "{}", self.retval)

src/core.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9-
use std::fmt;
9+
use reflection;
1010

1111
/// Trait for generically evaluating a type against a dynamically created
1212
/// predicate function.
@@ -15,7 +15,7 @@ use std::fmt;
1515
/// mean that the evaluated item is in some sort of pre-defined set. This is
1616
/// different from `Ord` and `Eq` in that an `item` will almost never be the
1717
/// same type as the implementing `Predicate` type.
18-
pub trait Predicate<Item: ?Sized>: fmt::Display {
18+
pub trait Predicate<Item: ?Sized>: reflection::PredicateReflection {
1919
/// Execute this `Predicate` against `variable`, returning the resulting
2020
/// boolean.
2121
fn eval(&self, variable: &Item) -> bool;

src/float/close.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::fmt;
1111
use float_cmp::ApproxEq;
1212
use float_cmp::Ulps;
1313

14+
use reflection;
1415
use Predicate;
1516

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

90+
impl reflection::PredicateReflection for IsClosePredicate {}
91+
8992
impl fmt::Display for IsClosePredicate {
9093
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9194
write!(

src/function.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use std::fmt;
1212
use std::marker::PhantomData;
1313

14+
use reflection;
1415
use Predicate;
1516

1617
/// Predicate that wraps a function over a reference that returns a `bool`.
@@ -60,6 +61,12 @@ where
6061
}
6162
}
6263

64+
impl<F, T> reflection::PredicateReflection for FnPredicate<F, T>
65+
where
66+
F: Fn(&T) -> bool,
67+
{
68+
}
69+
6370
impl<F, T> fmt::Display for FnPredicate<F, T>
6471
where
6572
F: Fn(&T) -> bool,

src/iter.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use std::fmt;
1313
use std::hash::Hash;
1414
use std::iter::FromIterator;
1515

16+
use reflection;
1617
use Predicate;
1718

1819
/// Predicate that returns `true` if `variable` is a member of the pre-defined
@@ -84,6 +85,12 @@ where
8485
}
8586
}
8687

88+
impl<T> reflection::PredicateReflection for InPredicate<T>
89+
where
90+
T: PartialEq + fmt::Debug,
91+
{
92+
}
93+
8794
impl<T> fmt::Display for InPredicate<T>
8895
where
8996
T: PartialEq + fmt::Debug,
@@ -167,6 +174,12 @@ where
167174
}
168175
}
169176

177+
impl<T> reflection::PredicateReflection for OrdInPredicate<T>
178+
where
179+
T: Ord + fmt::Debug,
180+
{
181+
}
182+
170183
impl<T> fmt::Display for OrdInPredicate<T>
171184
where
172185
T: Ord + fmt::Debug,
@@ -211,6 +224,12 @@ where
211224
}
212225
}
213226

227+
impl<T> reflection::PredicateReflection for HashableInPredicate<T>
228+
where
229+
T: Hash + Eq + fmt::Debug,
230+
{
231+
}
232+
214233
impl<T> fmt::Display for HashableInPredicate<T>
215234
where
216235
T: Hash + Eq + fmt::Debug,

src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
//! *variable == 42
7070
//! }
7171
//! }
72+
//! impl predicates::reflection::PredicateReflection for IsTheAnswer {}
7273
//! impl fmt::Display for IsTheAnswer {
7374
//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7475
//! write!(f, "var.is_the_answer()")
@@ -101,9 +102,10 @@ extern crate regex;
101102
pub mod prelude;
102103

103104
mod core;
104-
pub use core::Predicate;
105+
pub use core::*;
105106
mod boxed;
106-
pub use boxed::BoxPredicate;
107+
pub use boxed::*;
108+
pub mod reflection;
107109

108110
// core predicates
109111
pub mod constant;

src/name.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use std::fmt;
1212
use std::marker::PhantomData;
1313

14+
use reflection;
1415
use Predicate;
1516

1617
/// Augment an existing predicate with a name.
@@ -37,6 +38,13 @@ where
3738
}
3839
}
3940

41+
impl<M, Item> reflection::PredicateReflection for NamePredicate<M, Item>
42+
where
43+
M: Predicate<Item>,
44+
Item: ?Sized,
45+
{
46+
}
47+
4048
impl<M, Item> fmt::Display for NamePredicate<M, Item>
4149
where
4250
M: Predicate<Item>,

src/ord.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
1111
use std::fmt;
1212

13+
use reflection;
1314
use Predicate;
1415

1516
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -65,6 +66,12 @@ where
6566
}
6667
}
6768

69+
impl<T> reflection::PredicateReflection for EqPredicate<T>
70+
where
71+
T: fmt::Debug + PartialEq,
72+
{
73+
}
74+
6875
impl<T> fmt::Display for EqPredicate<T>
6976
where
7077
T: fmt::Debug + PartialEq,
@@ -183,6 +190,12 @@ where
183190
}
184191
}
185192

193+
impl<T> reflection::PredicateReflection for OrdPredicate<T>
194+
where
195+
T: fmt::Debug + PartialOrd,
196+
{
197+
}
198+
186199
impl<T> fmt::Display for OrdPredicate<T>
187200
where
188201
T: fmt::Debug + PartialOrd,

src/path/existence.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use std::fmt;
1010
use std::path;
1111

12+
use reflection;
1213
use Predicate;
1314

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

29+
impl reflection::PredicateReflection for ExistencePredicate {}
30+
2831
impl fmt::Display for ExistencePredicate {
2932
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3033
write!(f, "{}(var)", if self.exists { "exists" } else { "missing" })

src/path/fc.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::fs;
1111
use std::io::{self, Read};
1212
use std::path;
1313

14+
use reflection;
1415
use Predicate;
1516

1617
fn read_file(path: &path::Path) -> io::Result<Vec<u8>> {
@@ -40,6 +41,12 @@ where
4041
}
4142
}
4243

44+
impl<P> reflection::PredicateReflection for FileContentPredicate<P>
45+
where
46+
P: Predicate<[u8]>,
47+
{
48+
}
49+
4350
impl<P> fmt::Display for FileContentPredicate<P>
4451
where
4552
P: Predicate<[u8]>,

src/path/fs.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::fs;
1111
use std::io::{self, Read};
1212
use std::path;
1313

14+
use reflection;
1415
use Predicate;
1516

1617
fn read_file(path: &path::Path) -> io::Result<Vec<u8>> {
@@ -58,6 +59,8 @@ impl Predicate<path::Path> for BinaryFilePredicate {
5859
}
5960
}
6061

62+
impl reflection::PredicateReflection for BinaryFilePredicate {}
63+
6164
impl fmt::Display for BinaryFilePredicate {
6265
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6366
write!(f, "var is {}", self.path.display())
@@ -100,6 +103,8 @@ impl StrFilePredicate {
100103
}
101104
}
102105

106+
impl reflection::PredicateReflection for StrFilePredicate {}
107+
103108
impl fmt::Display for StrFilePredicate {
104109
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105110
write!(f, "var is {}", self.path.display())

src/path/ft.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::fs;
1111
use std::io;
1212
use std::path;
1313

14+
use reflection;
1415
use Predicate;
1516

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

98+
impl reflection::PredicateReflection for FileTypePredicate {}
99+
97100
impl fmt::Display for FileTypePredicate {
98101
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99102
write!(f, "var is {}", self.ft)

0 commit comments

Comments
 (0)