1 //! Sources for key-value pairs. 2 3 use std::fmt; 4 use kv::{Error, Key, ToKey, Value, ToValue}; 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 Visitor<'kvs>) -> Result<(), Error>22 fn visit<'kvs>(&'kvs self, visitor: &mut 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 { 50 key, 51 found: None, 52 }; 53 54 let _ = self.visit(&mut get); 55 get.found 56 } 57 58 /// Count the number of key-value pairs that can be visited. 59 /// 60 /// # Implementation notes 61 /// 62 /// A source that knows the number of key-value pairs upfront may provide a more 63 /// efficient implementation. 64 /// 65 /// A subsequent call to `visit` should yield the same number of key-value pairs 66 /// to the visitor, unless that visitor fails part way through. count(&self) -> usize67 fn count(&self) -> usize { 68 struct Count(usize); 69 70 impl<'kvs> Visitor<'kvs> for Count { 71 fn visit_pair(&mut self, _: Key<'kvs>, _: Value<'kvs>) -> Result<(), Error> { 72 self.0 += 1; 73 74 Ok(()) 75 } 76 } 77 78 let mut count = Count(0); 79 let _ = self.visit(&mut count); 80 count.0 81 } 82 } 83 84 impl<'a, T> Source for &'a T 85 where 86 T: Source + ?Sized, 87 { visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>88 fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> { 89 Source::visit(&**self, visitor) 90 } 91 get<'v>(&'v self, key: Key) -> Option<Value<'v>>92 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 93 Source::get(&**self, key) 94 } 95 count(&self) -> usize96 fn count(&self) -> usize { 97 Source::count(&**self) 98 } 99 } 100 101 impl<K, V> Source for (K, V) 102 where 103 K: ToKey, 104 V: ToValue, 105 { visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>106 fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> { 107 visitor.visit_pair(self.0.to_key(), self.1.to_value()) 108 } 109 get<'v>(&'v self, key: Key) -> Option<Value<'v>>110 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 111 if self.0.to_key() == key { 112 Some(self.1.to_value()) 113 } else { 114 None 115 } 116 } 117 count(&self) -> usize118 fn count(&self) -> usize { 119 1 120 } 121 } 122 123 impl<S> Source for [S] 124 where 125 S: Source, 126 { visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>127 fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> { 128 for source in self { 129 source.visit(visitor)?; 130 } 131 132 Ok(()) 133 } 134 count(&self) -> usize135 fn count(&self) -> usize { 136 self.len() 137 } 138 } 139 140 impl<S> Source for Option<S> 141 where 142 S: Source, 143 { visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>144 fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> { 145 if let Some(ref source) = *self { 146 source.visit(visitor)?; 147 } 148 149 Ok(()) 150 } 151 count(&self) -> usize152 fn count(&self) -> usize { 153 self.as_ref().map(Source::count).unwrap_or(0) 154 } 155 } 156 157 /// A visitor for the key-value pairs in a [`Source`](trait.Source.html). 158 pub trait Visitor<'kvs> { 159 /// Visit a key-value pair. visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>160 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>; 161 } 162 163 impl<'a, 'kvs, T> Visitor<'kvs> for &'a mut T 164 where 165 T: Visitor<'kvs> + ?Sized, 166 { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>167 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 168 (**self).visit_pair(key, value) 169 } 170 } 171 172 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugMap<'a, 'b> { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>173 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 174 self.entry(&key, &value); 175 Ok(()) 176 } 177 } 178 179 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugList<'a, 'b> { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>180 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 181 self.entry(&(key, value)); 182 Ok(()) 183 } 184 } 185 186 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugSet<'a, 'b> { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>187 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 188 self.entry(&(key, value)); 189 Ok(()) 190 } 191 } 192 193 impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugTuple<'a, 'b> { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>194 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 195 self.field(&key); 196 self.field(&value); 197 Ok(()) 198 } 199 } 200 201 #[cfg(feature = "std")] 202 mod std_support { 203 use super::*; 204 use std::borrow::Borrow; 205 use std::collections::{BTreeMap, HashMap}; 206 use std::hash::{BuildHasher, Hash}; 207 208 impl<S> Source for Box<S> 209 where 210 S: Source + ?Sized, 211 { visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>212 fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> { 213 Source::visit(&**self, visitor) 214 } 215 get<'v>(&'v self, key: Key) -> Option<Value<'v>>216 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 217 Source::get(&**self, key) 218 } 219 count(&self) -> usize220 fn count(&self) -> usize { 221 Source::count(&**self) 222 } 223 } 224 225 impl<S> Source for Vec<S> 226 where 227 S: Source, 228 { visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>229 fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> { 230 Source::visit(&**self, visitor) 231 } 232 get<'v>(&'v self, key: Key) -> Option<Value<'v>>233 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 234 Source::get(&**self, key) 235 } 236 count(&self) -> usize237 fn count(&self) -> usize { 238 Source::count(&**self) 239 } 240 } 241 242 impl<'kvs, V> Visitor<'kvs> for Box<V> 243 where 244 V: Visitor<'kvs> + ?Sized, 245 { visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>246 fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { 247 (**self).visit_pair(key, value) 248 } 249 } 250 251 impl<K, V, S> Source for HashMap<K, V, S> 252 where 253 K: ToKey + Borrow<str> + Eq + Hash, 254 V: ToValue, 255 S: BuildHasher, 256 { visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>257 fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> { 258 for (key, value) in self { 259 visitor.visit_pair(key.to_key(), value.to_value())?; 260 } 261 Ok(()) 262 } 263 get<'v>(&'v self, key: Key) -> Option<Value<'v>>264 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 265 HashMap::get(self, key.as_str()).map(|v| v.to_value()) 266 } 267 count(&self) -> usize268 fn count(&self) -> usize { 269 self.len() 270 } 271 } 272 273 impl<K, V> Source for BTreeMap<K, V> 274 where 275 K: ToKey + Borrow<str> + Ord, 276 V: ToValue, 277 { visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error>278 fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> { 279 for (key, value) in self { 280 visitor.visit_pair(key.to_key(), value.to_value())?; 281 } 282 Ok(()) 283 } 284 get<'v>(&'v self, key: Key) -> Option<Value<'v>>285 fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> { 286 BTreeMap::get(self, key.as_str()).map(|v| v.to_value()) 287 } 288 count(&self) -> usize289 fn count(&self) -> usize { 290 self.len() 291 } 292 } 293 294 #[cfg(test)] 295 mod tests { 296 use super::*; 297 use kv::value::test::Token; 298 use std::collections::{BTreeMap, HashMap}; 299 300 #[test] count()301 fn count() { 302 assert_eq!(1, Source::count(&Box::new(("a", 1)))); 303 assert_eq!(2, Source::count(&vec![("a", 1), ("b", 2)])); 304 } 305 306 #[test] get()307 fn get() { 308 let source = vec![("a", 1), ("b", 2), ("a", 1)]; 309 assert_eq!( 310 Token::I64(1), 311 Source::get(&source, Key::from_str("a")).unwrap().to_token() 312 ); 313 314 let source = Box::new(Option::None::<(&str, i32)>); 315 assert!(Source::get(&source, Key::from_str("a")).is_none()); 316 } 317 318 #[test] hash_map()319 fn hash_map() { 320 let mut map = HashMap::new(); 321 map.insert("a", 1); 322 map.insert("b", 2); 323 324 assert_eq!(2, Source::count(&map)); 325 assert_eq!( 326 Token::I64(1), 327 Source::get(&map, Key::from_str("a")).unwrap().to_token() 328 ); 329 } 330 331 #[test] btree_map()332 fn btree_map() { 333 let mut map = BTreeMap::new(); 334 map.insert("a", 1); 335 map.insert("b", 2); 336 337 assert_eq!(2, Source::count(&map)); 338 assert_eq!( 339 Token::I64(1), 340 Source::get(&map, Key::from_str("a")).unwrap().to_token() 341 ); 342 } 343 } 344 } 345 346 #[cfg(test)] 347 mod tests { 348 use super::*; 349 use kv::value::test::Token; 350 351 #[test] source_is_object_safe()352 fn source_is_object_safe() { 353 fn _check(_: &Source) {} 354 } 355 356 #[test] visitor_is_object_safe()357 fn visitor_is_object_safe() { 358 fn _check(_: &Visitor) {} 359 } 360 361 #[test] count()362 fn count() { 363 struct OnePair { 364 key: &'static str, 365 value: i32, 366 } 367 368 impl Source for OnePair { 369 fn visit<'kvs>(&'kvs self, visitor: &mut Visitor<'kvs>) -> Result<(), Error> { 370 visitor.visit_pair(self.key.to_key(), self.value.to_value()) 371 } 372 } 373 374 assert_eq!(1, Source::count(&("a", 1))); 375 assert_eq!(2, Source::count(&[("a", 1), ("b", 2)] as &[_])); 376 assert_eq!(0, Source::count(&Option::None::<(&str, i32)>)); 377 assert_eq!(1, Source::count(&OnePair { key: "a", value: 1 })); 378 } 379 380 #[test] get()381 fn get() { 382 let source = &[("a", 1), ("b", 2), ("a", 1)] as &[_]; 383 assert_eq!( 384 Token::I64(1), 385 Source::get(source, Key::from_str("a")).unwrap().to_token() 386 ); 387 assert_eq!( 388 Token::I64(2), 389 Source::get(source, Key::from_str("b")).unwrap().to_token() 390 ); 391 assert!(Source::get(&source, Key::from_str("c")).is_none()); 392 393 let source = Option::None::<(&str, i32)>; 394 assert!(Source::get(&source, Key::from_str("a")).is_none()); 395 } 396 } 397