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