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<dyn Iterator<Item = Parameter<'a>> + 'a>18     fn parameters<'a>(&'a self) -> Box<dyn 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<dyn Iterator<Item = Child<'a>> + 'a>24     fn children<'a>(&'a self) -> Box<dyn 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 dyn fmt::Display);
39 
40 impl<'a> Parameter<'a> {
41     /// Create a new `Parameter`.
new(key: &'a str, value: &'a dyn fmt::Display) -> Self42     pub fn new(key: &'a str, value: &'a dyn fmt::Display) -> Self {
43         Self(key, 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) -> &dyn fmt::Display52     pub fn value(&self) -> &dyn 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 dyn PredicateReflection);
71 
72 impl<'a> Child<'a> {
73     /// Create a new `Predicate` child.
new(key: &'a str, value: &'a dyn PredicateReflection) -> Self74     pub fn new(key: &'a str, value: &'a dyn PredicateReflection) -> Self {
75         Self(key, 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) -> &dyn PredicateReflection84     pub fn value(&self) -> &dyn 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 dyn 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 dyn PredicateReflection>, result: bool) -> Self111     pub fn new(predicate: Option<&'a dyn 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<&dyn PredicateReflection>133     pub fn predicate(&self) -> Option<&dyn 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) -> CaseProducts<'_>143     pub fn products(&self) -> CaseProducts<'_> {
144         CaseProducts(self.products.iter())
145     }
146 
147     /// Access the sub-cases.
children(&self) -> CaseChildren<'_>148     pub fn children(&self) -> CaseChildren<'_> {
149         CaseChildren(self.children.iter())
150     }
151 }
152 
153 impl<'a> fmt::Debug for Case<'a> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result154     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155         let predicate = if let Some(ref predicate) = self.predicate {
156             format!("Some({})", predicate)
157         } else {
158             "None".to_owned()
159         };
160         f.debug_struct("Case")
161             .field("predicate", &predicate)
162             .field("result", &self.result)
163             .field("products", &self.products)
164             .field("children", &self.children)
165             .finish()
166     }
167 }
168 
169 /// Iterator over a `Case`s by-products.
170 #[derive(Debug, Clone)]
171 pub struct CaseProducts<'a>(slice::Iter<'a, Product>);
172 
173 impl<'a> Iterator for CaseProducts<'a> {
174     type Item = &'a Product;
175 
next(&mut self) -> Option<&'a Product>176     fn next(&mut self) -> Option<&'a Product> {
177         self.0.next()
178     }
179 
size_hint(&self) -> (usize, Option<usize>)180     fn size_hint(&self) -> (usize, Option<usize>) {
181         self.0.size_hint()
182     }
183 
count(self) -> usize184     fn count(self) -> usize {
185         self.0.count()
186     }
187 }
188 
189 /// Iterator over a `Case`s sub-cases.
190 #[derive(Debug, Clone)]
191 pub struct CaseChildren<'a>(slice::Iter<'a, Case<'a>>);
192 
193 impl<'a> Iterator for CaseChildren<'a> {
194     type Item = &'a Case<'a>;
195 
next(&mut self) -> Option<&'a Case<'a>>196     fn next(&mut self) -> Option<&'a Case<'a>> {
197         self.0.next()
198     }
199 
size_hint(&self) -> (usize, Option<usize>)200     fn size_hint(&self) -> (usize, Option<usize>) {
201         self.0.size_hint()
202     }
203 
count(self) -> usize204     fn count(self) -> usize {
205         self.0.count()
206     }
207 }
208 
209 /// A by-product of a predicate evaluation.
210 ///
211 /// ```rust
212 /// use predicates_core;
213 ///
214 /// let product = predicates_core::reflection::Product::new("key", "value");
215 /// println!("{}", product);
216 /// let product = predicates_core::reflection::Product::new(format!("key-{}", 5), 30);
217 /// println!("{}", product);
218 /// ```
219 pub struct Product(borrow::Cow<'static, str>, Box<dyn fmt::Display>);
220 
221 impl Product {
222     /// Create a new `Product`.
new<S, D>(key: S, value: D) -> Self where S: Into<borrow::Cow<'static, str>>, D: fmt::Display + 'static,223     pub fn new<S, D>(key: S, value: D) -> Self
224     where
225         S: Into<borrow::Cow<'static, str>>,
226         D: fmt::Display + 'static,
227     {
228         Self(key.into(), Box::new(value))
229     }
230 
231     /// Access the `Product` name.
name(&self) -> &str232     pub fn name(&self) -> &str {
233         self.0.as_ref()
234     }
235 
236     /// Access the `Product` value.
value(&self) -> &dyn fmt::Display237     pub fn value(&self) -> &dyn fmt::Display {
238         &self.1
239     }
240 }
241 
242 impl fmt::Display for Product {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result243     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
244         write!(f, "{}: {}", self.0, self.1)
245     }
246 }
247 
248 impl fmt::Debug for Product {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result249     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
250         write!(f, "({:?}, {})", self.0, self.1)
251     }
252 }
253