Skip to content

Commit 12513b5

Browse files
committed
feat: Implement reflection for predicates
This also saw an audit of predicates to ensure their `Display` would most likely remain as one line of text. Anything in a `Display` that seemed likely to overflow was moved to a `Parameter`.
1 parent 5a6bf6b commit 12513b5

14 files changed

+166
-37
lines changed

src/boolean.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ where
6262
M2: Predicate<Item>,
6363
Item: ?Sized,
6464
{
65+
fn children<'a>(&'a self) -> Box<Iterator<Item = reflection::Child<'a>> + 'a> {
66+
let params = vec![
67+
reflection::Child::new("left", &self.a),
68+
reflection::Child::new("right", &self.b),
69+
];
70+
Box::new(params.into_iter())
71+
}
6572
}
6673

6774
impl<M1, M2, Item> fmt::Display for AndPredicate<M1, M2, Item>
@@ -123,6 +130,13 @@ where
123130
M2: Predicate<Item>,
124131
Item: ?Sized,
125132
{
133+
fn children<'a>(&'a self) -> Box<Iterator<Item = reflection::Child<'a>> + 'a> {
134+
let params = vec![
135+
reflection::Child::new("left", &self.a),
136+
reflection::Child::new("right", &self.b),
137+
];
138+
Box::new(params.into_iter())
139+
}
126140
}
127141

128142
impl<M1, M2, Item> fmt::Display for OrPredicate<M1, M2, Item>
@@ -178,6 +192,10 @@ where
178192
M: Predicate<Item>,
179193
Item: ?Sized,
180194
{
195+
fn children<'a>(&'a self) -> Box<Iterator<Item = reflection::Child<'a>> + 'a> {
196+
let params = vec![reflection::Child::new("predicate", &self.inner)];
197+
Box::new(params.into_iter())
198+
}
181199
}
182200

183201
impl<M, Item> fmt::Display for NotPredicate<M, Item>

src/boxed.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ impl<Item> reflection::PredicateReflection for BoxPredicate<Item>
4545
where
4646
Item: ?Sized,
4747
{
48+
fn parameters<'a>(&'a self) -> Box<Iterator<Item = reflection::Parameter<'a>> + 'a> {
49+
self.0.parameters()
50+
}
51+
52+
fn children<'a>(&'a self) -> Box<Iterator<Item = reflection::Child<'a>> + 'a> {
53+
self.0.children()
54+
}
4855
}
4956

5057
impl<Item> fmt::Display for BoxPredicate<Item>

src/constant.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ impl<Item> Predicate<Item> for BooleanPredicate<Item> {
2929
}
3030
}
3131

32-
impl<Item> reflection::PredicateReflection for BooleanPredicate<Item> {}
32+
impl<Item> reflection::PredicateReflection for BooleanPredicate<Item> {
33+
fn parameters<'a>(&'a self) -> Box<Iterator<Item = reflection::Parameter<'a>> + 'a> {
34+
let params = vec![reflection::Parameter::new("value", &self.retval)];
35+
Box::new(params.into_iter())
36+
}
37+
}
3338

3439
impl<Item> fmt::Display for BooleanPredicate<Item> {
3540
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

src/float/close.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,19 @@ impl Predicate<f64> for IsClosePredicate {
8787
}
8888
}
8989

90-
impl reflection::PredicateReflection for IsClosePredicate {}
90+
impl reflection::PredicateReflection for IsClosePredicate {
91+
fn parameters<'a>(&'a self) -> Box<Iterator<Item = reflection::Parameter<'a>> + 'a> {
92+
let params = vec![
93+
reflection::Parameter::new("epsilon", &self.epsilon),
94+
reflection::Parameter::new("ulps", &self.ulps),
95+
];
96+
Box::new(params.into_iter())
97+
}
98+
}
9199

92100
impl fmt::Display for IsClosePredicate {
93101
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94-
write!(
95-
f,
96-
"var ~= {} +/- {} ({})",
97-
self.target, self.epsilon, self.ulps
98-
)
102+
write!(f, "var ~= {}", self.target)
99103
}
100104
}
101105

src/iter.rs

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub struct InPredicate<T>
3030
where
3131
T: PartialEq + fmt::Debug,
3232
{
33-
inner: Vec<T>,
33+
inner: reflection::DebugAdapter<Vec<T>>,
3434
}
3535

3636
impl<T> InPredicate<T>
@@ -61,9 +61,11 @@ where
6161
/// assert_eq!(true, predicate_fn.eval("c"));
6262
/// ```
6363
pub fn sort(self) -> OrdInPredicate<T> {
64-
let mut items = self.inner;
64+
let mut items = self.inner.debug;
6565
items.sort();
66-
OrdInPredicate { inner: items }
66+
OrdInPredicate {
67+
inner: reflection::DebugAdapter::new(items),
68+
}
6769
}
6870
}
6971

@@ -72,7 +74,7 @@ where
7274
T: PartialEq + fmt::Debug,
7375
{
7476
fn eval(&self, variable: &T) -> bool {
75-
self.inner.contains(variable)
77+
self.inner.debug.contains(variable)
7678
}
7779
}
7880

@@ -81,22 +83,26 @@ where
8183
T: PartialEq + fmt::Debug + ?Sized,
8284
{
8385
fn eval(&self, variable: &T) -> bool {
84-
self.inner.contains(&variable)
86+
self.inner.debug.contains(&variable)
8587
}
8688
}
8789

8890
impl<T> reflection::PredicateReflection for InPredicate<T>
8991
where
9092
T: PartialEq + fmt::Debug,
9193
{
94+
fn parameters<'a>(&'a self) -> Box<Iterator<Item = reflection::Parameter<'a>> + 'a> {
95+
let params = vec![reflection::Parameter::new("values", &self.inner)];
96+
Box::new(params.into_iter())
97+
}
9298
}
9399

94100
impl<T> fmt::Display for InPredicate<T>
95101
where
96102
T: PartialEq + fmt::Debug,
97103
{
98104
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99-
write!(f, "var in {:?}", self.inner)
105+
write!(f, "var in values")
100106
}
101107
}
102108

@@ -135,7 +141,7 @@ where
135141
I: IntoIterator<Item = T>,
136142
{
137143
InPredicate {
138-
inner: Vec::from_iter(iter),
144+
inner: reflection::DebugAdapter::new(Vec::from_iter(iter)),
139145
}
140146
}
141147

@@ -153,15 +159,15 @@ pub struct OrdInPredicate<T>
153159
where
154160
T: Ord + fmt::Debug,
155161
{
156-
inner: Vec<T>,
162+
inner: reflection::DebugAdapter<Vec<T>>,
157163
}
158164

159165
impl<T> Predicate<T> for OrdInPredicate<T>
160166
where
161167
T: Ord + fmt::Debug,
162168
{
163169
fn eval(&self, variable: &T) -> bool {
164-
self.inner.binary_search(variable).is_ok()
170+
self.inner.debug.binary_search(variable).is_ok()
165171
}
166172
}
167173

@@ -170,22 +176,26 @@ where
170176
T: Ord + fmt::Debug + ?Sized,
171177
{
172178
fn eval(&self, variable: &T) -> bool {
173-
self.inner.binary_search(&variable).is_ok()
179+
self.inner.debug.binary_search(&variable).is_ok()
174180
}
175181
}
176182

177183
impl<T> reflection::PredicateReflection for OrdInPredicate<T>
178184
where
179185
T: Ord + fmt::Debug,
180186
{
187+
fn parameters<'a>(&'a self) -> Box<Iterator<Item = reflection::Parameter<'a>> + 'a> {
188+
let params = vec![reflection::Parameter::new("values", &self.inner)];
189+
Box::new(params.into_iter())
190+
}
181191
}
182192

183193
impl<T> fmt::Display for OrdInPredicate<T>
184194
where
185195
T: Ord + fmt::Debug,
186196
{
187197
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
188-
write!(f, "var in {:?}", self.inner)
198+
write!(f, "var in values")
189199
}
190200
}
191201

@@ -203,15 +213,15 @@ pub struct HashableInPredicate<T>
203213
where
204214
T: Hash + Eq + fmt::Debug,
205215
{
206-
inner: HashSet<T>,
216+
inner: reflection::DebugAdapter<HashSet<T>>,
207217
}
208218

209219
impl<T> Predicate<T> for HashableInPredicate<T>
210220
where
211221
T: Hash + Eq + fmt::Debug,
212222
{
213223
fn eval(&self, variable: &T) -> bool {
214-
self.inner.contains(variable)
224+
self.inner.debug.contains(variable)
215225
}
216226
}
217227

@@ -220,22 +230,26 @@ where
220230
T: Hash + Eq + fmt::Debug + ?Sized,
221231
{
222232
fn eval(&self, variable: &T) -> bool {
223-
self.inner.contains(&variable)
233+
self.inner.debug.contains(&variable)
224234
}
225235
}
226236

227237
impl<T> reflection::PredicateReflection for HashableInPredicate<T>
228238
where
229239
T: Hash + Eq + fmt::Debug,
230240
{
241+
fn parameters<'a>(&'a self) -> Box<Iterator<Item = reflection::Parameter<'a>> + 'a> {
242+
let params = vec![reflection::Parameter::new("values", &self.inner)];
243+
Box::new(params.into_iter())
244+
}
231245
}
232246

233247
impl<T> fmt::Display for HashableInPredicate<T>
234248
where
235249
T: Hash + Eq + fmt::Debug,
236250
{
237251
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
238-
write!(f, "var in {:?}", self.inner)
252+
write!(f, "var in values")
239253
}
240254
}
241255

@@ -268,6 +282,6 @@ where
268282
I: IntoIterator<Item = T>,
269283
{
270284
HashableInPredicate {
271-
inner: HashSet::from_iter(iter),
285+
inner: reflection::DebugAdapter::new(HashSet::from_iter(iter)),
272286
}
273287
}

src/name.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ where
4343
M: Predicate<Item>,
4444
Item: ?Sized,
4545
{
46+
fn children<'a>(&'a self) -> Box<Iterator<Item = reflection::Child<'a>> + 'a> {
47+
let params = vec![reflection::Child::new(self.name, &self.inner)];
48+
Box::new(params.into_iter())
49+
}
4650
}
4751

4852
impl<M, Item> fmt::Display for NamePredicate<M, Item>

src/path/fc.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ impl<P> reflection::PredicateReflection for FileContentPredicate<P>
4545
where
4646
P: Predicate<[u8]>,
4747
{
48+
fn children<'a>(&'a self) -> Box<Iterator<Item = reflection::Child<'a>> + 'a> {
49+
let params = vec![reflection::Child::new("predicate", &self.p)];
50+
Box::new(params.into_iter())
51+
}
4852
}
4953

5054
impl<P> fmt::Display for FileContentPredicate<P>

src/path/fs.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ fn read_file(path: &path::Path) -> io::Result<Vec<u8>> {
2424
#[derive(Debug, Clone, PartialEq, Eq)]
2525
pub struct BinaryFilePredicate {
2626
path: path::PathBuf,
27-
content: Vec<u8>,
27+
content: reflection::DebugAdapter<Vec<u8>>,
2828
}
2929

3030
impl BinaryFilePredicate {
3131
fn eval(&self, path: &path::Path) -> io::Result<bool> {
3232
let content = read_file(path)?;
33-
Ok(self.content == content)
33+
Ok(self.content.debug == content)
3434
}
3535

3636
/// Creates a new `Predicate` that ensures complete equality
@@ -48,7 +48,7 @@ impl BinaryFilePredicate {
4848
/// ```
4949
pub fn utf8(self) -> Option<StrFilePredicate> {
5050
let path = self.path;
51-
let content = String::from_utf8(self.content).ok()?;
51+
let content = String::from_utf8(self.content.debug).ok()?;
5252
Some(StrFilePredicate { path, content })
5353
}
5454
}
@@ -59,7 +59,12 @@ impl Predicate<path::Path> for BinaryFilePredicate {
5959
}
6060
}
6161

62-
impl reflection::PredicateReflection for BinaryFilePredicate {}
62+
impl reflection::PredicateReflection for BinaryFilePredicate {
63+
fn parameters<'a>(&'a self) -> Box<Iterator<Item = reflection::Parameter<'a>> + 'a> {
64+
let params = vec![reflection::Parameter::new("content", &self.content)];
65+
Box::new(params.into_iter())
66+
}
67+
}
6368

6469
impl fmt::Display for BinaryFilePredicate {
6570
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -81,7 +86,7 @@ impl fmt::Display for BinaryFilePredicate {
8186
/// assert_eq!(false, predicate_file.eval(Path::new("Cargo.lock")));
8287
/// ```
8388
pub fn eq_file(path: &path::Path) -> BinaryFilePredicate {
84-
let content = read_file(path).unwrap();
89+
let content = reflection::DebugAdapter::new(read_file(path).unwrap());
8590
BinaryFilePredicate {
8691
path: path.to_path_buf(),
8792
content,
@@ -103,7 +108,12 @@ impl StrFilePredicate {
103108
}
104109
}
105110

106-
impl reflection::PredicateReflection for StrFilePredicate {}
111+
impl reflection::PredicateReflection for StrFilePredicate {
112+
fn parameters<'a>(&'a self) -> Box<Iterator<Item = reflection::Parameter<'a>> + 'a> {
113+
let params = vec![reflection::Parameter::new("content", &self.content)];
114+
Box::new(params.into_iter())
115+
}
116+
}
107117

108118
impl fmt::Display for StrFilePredicate {
109119
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

src/path/ft.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,12 @@ impl Predicate<path::Path> for FileTypePredicate {
9595
}
9696
}
9797

98-
impl reflection::PredicateReflection for FileTypePredicate {}
98+
impl reflection::PredicateReflection for FileTypePredicate {
99+
fn parameters<'a>(&'a self) -> Box<Iterator<Item = reflection::Parameter<'a>> + 'a> {
100+
let params = vec![reflection::Parameter::new("follow", &self.follow)];
101+
Box::new(params.into_iter())
102+
}
103+
}
99104

100105
impl fmt::Display for FileTypePredicate {
101106
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

0 commit comments

Comments
 (0)