1 // Copyright (c) 2018 The predicates-rs Project Developers.
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8 
9 //! Introspect into the state of a `Predicate`.
10 
11 use std::borrow;
12 use std::fmt;
13 use std::slice;
14 
15 /// Introspect the state of a `Predicate`.
16 pub trait PredicateReflection: fmt::Display {
17     /// Parameters of the current `Predicate`.
parameters<'a>(&'a self) -> Box<Iterator<Item = Parameter<'a>> + 'a>18     fn parameters<'a>(&'a self) -> Box<Iterator<Item = Parameter<'a>> + 'a> {
19         let params = vec![];
20         Box::new(params.into_iter())
21     }
22 
23     /// Nested `Predicate`s of the current `Predicate`.
children<'a>(&'a self) -> Box<Iterator<Item = Child<'a>> + 'a>24     fn children<'a>(&'a self) -> Box<Iterator<Item = Child<'a>> + 'a> {
25         let params = vec![];
26         Box::new(params.into_iter())
27     }
28 }
29 
30 /// A view of a `Predicate` parameter, provided by reflection.
31 ///
32 /// ```rust
33 /// use predicates_core;
34 ///
35 /// let param = predicates_core::reflection::Parameter::new("key", &10);
36 /// println!("{}", param);
37 /// ```
38 pub struct Parameter<'a>(&'a str, &'a fmt::Display);
39 
40 impl<'a> Parameter<'a> {
41     /// Create a new `Parameter`.
new(key: &'a str, value: &'a fmt::Display) -> Self42     pub fn new(key: &'a str, value: &'a fmt::Display) -> Self {
43         Self { 0: key, 1: value }
44     }
45 
46     /// Access the `Parameter` name.
name(&self) -> &str47     pub fn name(&self) -> &str {
48         self.0
49     }
50 
51     /// Access the `Parameter` value.
value(&self) -> &fmt::Display52     pub fn value(&self) -> &fmt::Display {
53         self.1
54     }
55 }
56 
57 impl<'a> fmt::Display for Parameter<'a> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result58     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59         write!(f, "{}: {}", self.0, self.1)
60     }
61 }
62 
63 impl<'a> fmt::Debug for Parameter<'a> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result64     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65         write!(f, "({:?}, {})", self.0, self.1)
66     }
67 }
68 
69 /// A view of a `Predicate` child, provided by reflection.
70 pub struct Child<'a>(&'a str, &'a PredicateReflection);
71 
72 impl<'a> Child<'a> {
73     /// Create a new `Predicate` child.
new(key: &'a str, value: &'a PredicateReflection) -> Self74     pub fn new(key: &'a str, value: &'a PredicateReflection) -> Self {
75         Self { 0: key, 1: value }
76     }
77 
78     /// Access the `Child`'s name.
name(&self) -> &str79     pub fn name(&self) -> &str {
80         self.0
81     }
82 
83     /// Access the `Child` `Predicate`.
value(&self) -> &PredicateReflection84     pub fn value(&self) -> &PredicateReflection {
85         self.1
86     }
87 }
88 
89 impl<'a> fmt::Display for Child<'a> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result90     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91         write!(f, "{}: {}", self.0, self.1)
92     }
93 }
94 
95 impl<'a> fmt::Debug for Child<'a> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result96     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97         write!(f, "({:?}, {})", self.0, self.1)
98     }
99 }
100 
101 /// A descriptive explanation for why a predicate failed.
102 pub struct Case<'a> {
103     predicate: Option<&'a PredicateReflection>,
104     result: bool,
105     products: Vec<Product>,
106     children: Vec<Case<'a>>,
107 }
108 
109 impl<'a> Case<'a> {
110     /// Create a new `Case` describing the result of a `Predicate`.
new(predicate: Option<&'a PredicateReflection>, result: bool) -> Self111     pub fn new(predicate: Option<&'a PredicateReflection>, result: bool) -> Self {
112         Self {
113             predicate,
114             result,
115             products: Default::default(),
116             children: Default::default(),
117         }
118     }
119 
120     /// Add an additional by product to a `Case`.
add_product(mut self, product: Product) -> Self121     pub fn add_product(mut self, product: Product) -> Self {
122         self.products.push(product);
123         self
124     }
125 
126     /// Add an additional by product to a `Case`.
add_child(mut self, child: Case<'a>) -> Self127     pub fn add_child(mut self, child: Case<'a>) -> Self {
128         self.children.push(child);
129         self
130     }
131 
132     /// The `Predicate` that produced this case.
predicate(&self) -> Option<&PredicateReflection>133     pub fn predicate(&self) -> Option<&PredicateReflection> {
134         self.predicate
135     }
136 
137     /// The result of this case.
result(&self) -> bool138     pub fn result(&self) -> bool {
139         self.result
140     }
141 
142     /// Access the by-products from determining this case.
products(&self) -> CaseProducts143     pub fn products(&self) -> CaseProducts {
144         CaseProducts {
145             0: self.products.iter(),
146         }
147     }
148 
149     /// Access the sub-cases.
children(&self) -> CaseChildren150     pub fn children(&self) -> CaseChildren {
151         CaseChildren {
152             0: self.children.iter(),
153         }
154     }
155 }
156 
157 impl<'a> fmt::Debug for Case<'a> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result158     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159         let predicate = if let Some(ref predicate) = self.predicate {
160             format!("Some({})", predicate)
161         } else {
162             "None".to_owned()
163         };
164         f.debug_struct("Case")
165             .field("predicate", &predicate)
166             .field("result", &self.result)
167             .field("products", &self.products)
168             .field("children", &self.children)
169             .finish()
170     }
171 }
172 
173 /// Iterator over a `Case`s by-products.
174 #[derive(Debug, Clone)]
175 pub struct CaseProducts<'a>(slice::Iter<'a, Product>);
176 
177 impl<'a> Iterator for CaseProducts<'a> {
178     type Item = &'a Product;
179 
next(&mut self) -> Option<&'a Product>180     fn next(&mut self) -> Option<&'a Product> {
181         self.0.next()
182     }
183 
size_hint(&self) -> (usize, Option<usize>)184     fn size_hint(&self) -> (usize, Option<usize>) {
185         self.0.size_hint()
186     }
187 
count(self) -> usize188     fn count(self) -> usize {
189         self.0.count()
190     }
191 }
192 
193 /// Iterator over a `Case`s sub-cases.
194 #[derive(Debug, Clone)]
195 pub struct CaseChildren<'a>(slice::Iter<'a, Case<'a>>);
196 
197 impl<'a> Iterator for CaseChildren<'a> {
198     type Item = &'a Case<'a>;
199 
next(&mut self) -> Option<&'a Case<'a>>200     fn next(&mut self) -> Option<&'a Case<'a>> {
201         self.0.next()
202     }
203 
size_hint(&self) -> (usize, Option<usize>)204     fn size_hint(&self) -> (usize, Option<usize>) {
205         self.0.size_hint()
206     }
207 
count(self) -> usize208     fn count(self) -> usize {
209         self.0.count()
210     }
211 }
212 
213 /// A by-product of a predicate evaluation.
214 ///
215 /// ```rust
216 /// use predicates_core;
217 ///
218 /// let product = predicates_core::reflection::Product::new("key", "value");
219 /// println!("{}", product);
220 /// let product = predicates_core::reflection::Product::new(format!("key-{}", 5), 30);
221 /// println!("{}", product);
222 /// ```
223 pub struct Product(borrow::Cow<'static, str>, Box<fmt::Display>);
224 
225 impl Product {
226     /// Create a new `Product`.
new<S, D>(key: S, value: D) -> Self where S: Into<borrow::Cow<'static, str>>, D: fmt::Display + 'static,227     pub fn new<S, D>(key: S, value: D) -> Self
228     where
229         S: Into<borrow::Cow<'static, str>>,
230         D: fmt::Display + 'static,
231     {
232         Self {
233             0: key.into(),
234             1: Box::new(value),
235         }
236     }
237 
238     /// Access the `Product` name.
name(&self) -> &str239     pub fn name(&self) -> &str {
240         self.0.as_ref()
241     }
242 
243     /// Access the `Product` value.
value(&self) -> &fmt::Display244     pub fn value(&self) -> &fmt::Display {
245         &self.1
246     }
247 }
248 
249 impl<'a> fmt::Display for Product {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result250     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
251         write!(f, "{}: {}", self.0, self.1)
252     }
253 }
254 
255 impl<'a> fmt::Debug for Product {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result256     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
257         write!(f, "({:?}, {})", self.0, self.1)
258     }
259 }
260