1 //! Sources for key-value pairs. 2 3 use kv::{Error, Key, ToKey, ToValue, Value}; 4 use std::fmt; 5 6 /// A source of key-value pairs. 7 /// 8 /// The source may be a single pair, a set of pairs, or a filter over a set of pairs. 9 /// Use the [`Visitor`](trait.Visitor.html) trait to inspect the structured data 10 /// in a source. 11 pub trait Source { 12 /// Visit key-value pairs. 13 /// 14 /// A source doesn't have to guarantee any ordering or uniqueness of key-value pairs. 15 /// If the given visitor returns an error then the source may early-return with it, 16 /// even if there are more key-value pairs. 17 /// 18 /// # Implementation notes 19 /// 20 /// A source should yield the same key-value pairs to a subsequent visitor unless 21 /// that visitor itself fails. visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>22 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>; 23 24 /// Get the value for a given key. 25 /// 26 /// If the key appears multiple times in the source then which key is returned 27 /// is implementation specific. 28 /// 29 /// # Implementation notes 30 /// 31 /// A source that can provide a more efficient implementation of this method 32 /// should override it. get<'v>(&'v self, key: Key) -> Option<Value<'v>>33 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 34 struct Get<'k, 'v> { 35 key: Key<'k>, 36 found: Option<Value<'v>>, 37 } 38 39 impl<'k, 'kvs> Visitor<'kvs> for Get<'k, 'kvs> { 40 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 41 if self.key == key { 42 self.found = Some(value); 43 } 44 45 Ok(()) 46 } 47 } 48 49 let mut get = Get { key, found: None }; 50 51 let _ = self.visit(&mut get); 52 get.found 53 } 54 55 /// Count the number of key-value pairs that can be visited. 56 /// 57 /// # Implementation notes 58 /// 59 /// A source that knows the number of key-value pairs upfront may provide a more 60 /// efficient implementation. 61 /// 62 /// A subsequent call to `visit` should yield the same number of key-value pairs 63 /// to the visitor, unless that visitor fails part way through. count(&self) -> usize64 fn count(&self) -> usize { 65 struct Count(usize); 66 67 impl<'kvs> Visitor<'kvs> for Count { 68 fn visit_pair(&mut self, _: Key<'kvs>, _: Value<'kvs>) -> Result<(), Error> { 69 self.0 += 1; 70 71 Ok(()) 72 } 73 } 74 75 let mut count = Count(0); 76 let _ = self.visit(&mut count); 77 count.0 78 } 79 } 80 81 impl<'a, T> Source for &'a T 82 where 83 T: Source + ?Sized, 84 { visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>85 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { 86 Source::visit(&**self, visitor) 87 } 88 get<'v>(&'v self, key: Key) -> Option<Value<'v>>89 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 90 Source::get(&**self, key) 91 } 92 count(&self) -> usize93 fn count(&self) -> usize { 94 Source::count(&**self) 95 } 96 } 97 98 impl<K, V> Source for (K, V) 99 where 100 K: ToKey, 101 V: ToValue, 102 { visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>103 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { 104 visitor.visit_pair(self.0.to_key(), self.1.to_value()) 105 } 106 get<'v>(&'v self, key: Key) -> Option<Value<'v>>107 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 108 if self.0.to_key() == key { 109 Some(self.1.to_value()) 110 } else { 111 None 112 } 113 } 114 count(&self) -> usize115 fn count(&self) -> usize { 116 1 117 } 118 } 119 120 impl<S> Source for [S] 121 where 122 S: Source, 123 { visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>124 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { 125 for source in self { 126 source.visit(visitor)?; 127 } 128 129 Ok(()) 130 } 131 count(&self) -> usize132 fn count(&self) -> usize { 133 self.len() 134 } 135 } 136 137 impl<S> Source for Option<S> 138 where 139 S: Source, 140 { visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>141 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { 142 if let Some(ref source) = *self { 143 source.visit(visitor)?; 144 } 145 146 Ok(()) 147 } 148 count(&self) -> usize149 fn count(&self) -> usize { 150 self.as_ref().map(Source::count).unwrap_or(0) 151 } 152 } 153 154 /// A visitor for the key-value pairs in a [`Source`](trait.Source.html). 155 pub trait Visitor<'kvs> { 156 /// Visit a key-value pair. visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>157 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>; 158 } 159 160 impl<'a, 'kvs, T> Visitor<'kvs> for &'a mut T 161 where 162 T: Visitor<'kvs> + ?Sized, 163 { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>164 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 165 (**self).visit_pair(key, value) 166 } 167 } 168 169 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugMap<'a, 'b> { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>170 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 171 self.entry(&key, &value); 172 Ok(()) 173 } 174 } 175 176 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugList<'a, 'b> { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>177 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 178 self.entry(&(key, value)); 179 Ok(()) 180 } 181 } 182 183 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugSet<'a, 'b> { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>184 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 185 self.entry(&(key, value)); 186 Ok(()) 187 } 188 } 189 190 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugTuple<'a, 'b> { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>191 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 192 self.field(&key); 193 self.field(&value); 194 Ok(()) 195 } 196 } 197 198 #[cfg(feature = "std")] 199 mod std_support { 200 use super::*; 201 use std::borrow::Borrow; 202 use std::collections::{BTreeMap, HashMap}; 203 use std::hash::{BuildHasher, Hash}; 204 205 impl<S> Source for Box<S> 206 where 207 S: Source + ?Sized, 208 { visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>209 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { 210 Source::visit(&**self, visitor) 211 } 212 get<'v>(&'v self, key: Key) -> Option<Value<'v>>213 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 214 Source::get(&**self, key) 215 } 216 count(&self) -> usize217 fn count(&self) -> usize { 218 Source::count(&**self) 219 } 220 } 221 222 impl<S> Source for Vec<S> 223 where 224 S: Source, 225 { visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>226 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { 227 Source::visit(&**self, visitor) 228 } 229 get<'v>(&'v self, key: Key) -> Option<Value<'v>>230 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 231 Source::get(&**self, key) 232 } 233 count(&self) -> usize234 fn count(&self) -> usize { 235 Source::count(&**self) 236 } 237 } 238 239 impl<'kvs, V> Visitor<'kvs> for Box<V> 240 where 241 V: Visitor<'kvs> + ?Sized, 242 { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>243 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 244 (**self).visit_pair(key, value) 245 } 246 } 247 248 impl<K, V, S> Source for HashMap<K, V, S> 249 where 250 K: ToKey + Borrow<str> + Eq + Hash, 251 V: ToValue, 252 S: BuildHasher, 253 { visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>254 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { 255 for (key, value) in self { 256 visitor.visit_pair(key.to_key(), value.to_value())?; 257 } 258 Ok(()) 259 } 260 get<'v>(&'v self, key: Key) -> Option<Value<'v>>261 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 262 HashMap::get(self, key.as_str()).map(|v| v.to_value()) 263 } 264 count(&self) -> usize265 fn count(&self) -> usize { 266 self.len() 267 } 268 } 269 270 impl<K, V> Source for BTreeMap<K, V> 271 where 272 K: ToKey + Borrow<str> + Ord, 273 V: ToValue, 274 { visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>275 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { 276 for (key, value) in self { 277 visitor.visit_pair(key.to_key(), value.to_value())?; 278 } 279 Ok(()) 280 } 281 get<'v>(&'v self, key: Key) -> Option<Value<'v>>282 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 283 BTreeMap::get(self, key.as_str()).map(|v| v.to_value()) 284 } 285 count(&self) -> usize286 fn count(&self) -> usize { 287 self.len() 288 } 289 } 290 291 #[cfg(test)] 292 mod tests { 293 use super::*; 294 use kv::value::test::Token; 295 use std::collections::{BTreeMap, HashMap}; 296 297 #[test] count()298 fn count() { 299 assert_eq!(1, Source::count(&Box::new(("a", 1)))); 300 assert_eq!(2, Source::count(&vec![("a", 1), ("b", 2)])); 301 } 302 303 #[test] get()304 fn get() { 305 let source = vec![("a", 1), ("b", 2), ("a", 1)]; 306 assert_eq!( 307 Token::I64(1), 308 Source::get(&source, Key::from_str("a")).unwrap().to_token() 309 ); 310 311 let source = Box::new(Option::None::<(&str, i32)>); 312 assert!(Source::get(&source, Key::from_str("a")).is_none()); 313 } 314 315 #[test] hash_map()316 fn hash_map() { 317 let mut map = HashMap::new(); 318 map.insert("a", 1); 319 map.insert("b", 2); 320 321 assert_eq!(2, Source::count(&map)); 322 assert_eq!( 323 Token::I64(1), 324 Source::get(&map, Key::from_str("a")).unwrap().to_token() 325 ); 326 } 327 328 #[test] btree_map()329 fn btree_map() { 330 let mut map = BTreeMap::new(); 331 map.insert("a", 1); 332 map.insert("b", 2); 333 334 assert_eq!(2, Source::count(&map)); 335 assert_eq!( 336 Token::I64(1), 337 Source::get(&map, Key::from_str("a")).unwrap().to_token() 338 ); 339 } 340 } 341 } 342 343 #[cfg(test)] 344 mod tests { 345 use super::*; 346 use kv::value::test::Token; 347 348 #[test] source_is_object_safe()349 fn source_is_object_safe() { 350 fn _check(_: &dyn Source) {} 351 } 352 353 #[test] visitor_is_object_safe()354 fn visitor_is_object_safe() { 355 fn _check(_: &dyn Visitor) {} 356 } 357 358 #[test] count()359 fn count() { 360 struct OnePair { 361 key: &'static str, 362 value: i32, 363 } 364 365 impl Source for OnePair { 366 fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { 367 visitor.visit_pair(self.key.to_key(), self.value.to_value()) 368 } 369 } 370 371 assert_eq!(1, Source::count(&("a", 1))); 372 assert_eq!(2, Source::count(&[("a", 1), ("b", 2)] as &[_])); 373 assert_eq!(0, Source::count(&Option::None::<(&str, i32)>)); 374 assert_eq!(1, Source::count(&OnePair { key: "a", value: 1 })); 375 } 376 377 #[test] get()378 fn get() { 379 let source = &[("a", 1), ("b", 2), ("a", 1)] as &[_]; 380 assert_eq!( 381 Token::I64(1), 382 Source::get(source, Key::from_str("a")).unwrap().to_token() 383 ); 384 assert_eq!( 385 Token::I64(2), 386 Source::get(source, Key::from_str("b")).unwrap().to_token() 387 ); 388 assert!(Source::get(&source, Key::from_str("c")).is_none()); 389 390 let source = Option::None::<(&str, i32)>; 391 assert!(Source::get(&source, Key::from_str("a")).is_none()); 392 } 393 } 394