1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
use std::collections::HashMap; use std::hash::{BuildHasher, Hash}; use std::sync::Arc; use crate::access::{iter::ReflectIter, Access, ReflectDirect}; use crate::climber::{ClimbError, Climber}; use crate::deser; use crate::node_tree::NodeTree; use crate::reflector::Reflector; impl<'a, K, V> ReflectIter<(&'a dyn Access, &'a dyn Access)> for std::collections::hash_map::Iter<'a, K, V> where K: Eq + Hash + Access, V: Access, { fn reflect_next(&mut self) -> Option<(&'a dyn Access, &'a dyn Access)> { match self.next() { None => None, Some((key, value)) => Some((key, value)), } } } impl<K, V, S> ReflectDirect for HashMap<K, V, S> where K: Eq + Hash + Access + deser::Deser, V: Access, S: BuildHasher, { fn immut_reflector(&self, reflector: &Arc<Reflector>) -> NodeTree { let mut i = Box::new(self.iter()); Reflector::reflect_map(reflector, &mut *i, "HashMap") } fn immut_climber<'a>(&self, climber: &mut Climber<'a>) -> Result<Option<NodeTree>, ClimbError> { if !climber.open_bracket() { return Ok(None); } let v = K::deser(&mut climber.borrow_tracker()) .map(|x| <HashMap<K, V, S>>::get(self, &x)) .map(|x| x.map(|y| y as &dyn Access)); let v = match v { Ok(None) => return Err(ClimbError::NotFound), Err(err) => return Err(ClimbError::DeserError(err)), Ok(Some(v)) => v, }; climber.close_bracket()?; return climber.general_access_immut(v).map(Some); } fn mut_climber<'a>( &mut self, climber: &mut Climber<'a>, ) -> Result<Option<NodeTree>, ClimbError> { if !climber.open_bracket() { return Ok(None); } let v = match K::deser(&mut climber.borrow_tracker()) { Ok(x) => Ok(match <HashMap<K, V, S>>::get_mut(self, &x) { None => None, Some(x) => Some(x), }), Err(e) => Err(e), }; let v = match v { Ok(None) => return Err(ClimbError::NotFound), Err(err) => return Err(ClimbError::DeserError(err)), Ok(Some(v)) => v, }; climber.close_bracket()?; return climber.general_access_mut(v).map(Some); } } use interact_derive::derive_interact_opaque; derive_interact_opaque! { #[interact(skip_bound(S))] #[interact(immut_fn(len()))] struct HashMap<K, V, S> where K: Eq + std::hash::Hash + deser::Deser, S: std::hash::BuildHasher; }