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 { 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) -> &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 { 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) -> &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 { 145 0: self.products.iter(), 146 } 147 } 148 149 /// Access the sub-cases. children(&self) -> CaseChildren<'_>150 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<dyn 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) -> &dyn fmt::Display244 pub fn value(&self) -> &dyn 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