[−][src]Module smart_access::collections
Implementation of At
for some collections.
Requires the collections
feature.
The following traits are implemented:
At<(), View=[T]> for Vec<T>
: the slice owned by the vectorAt<usize, View=T> for Vec<T>
: simple indexingAt<range, View=Vec<T>> for Vec<T>
: subvector (its size can be changed); Warning: access is O(n); consider passing to slices to get O(1) accessAt<&Q, View=V> for <Some>Map<K,V>
: access the value if it is presentAt<(K,V), View=V> for <Some>Map<K,V>
: ensure that the value is present (using the provided default) then access itAT<(K,V,M), View=V> for <Some>Map<K,V>
: if the value is present then preprocess it with a mutatorM
, otherwise insert the providedV
AT<&Q, View=T> for <Some>Set<T>
: access the value if it is presentAT<(T,()), View=T> for <Some>Set<T>
: ensure that the value is present then access itAT<(T,), View=<Some>Set<T>> for <Some>Set<T>
: ensure that the value is present
Though in normal circumstances these implementations do not panic
there exists a possibility of panicking. For example
At<range> for Vec<T>
splits vector into (at most) three parts
then glues them back after the update. Every of these actions
can panic on Out Of Memory.
Vector accessors
let mut foo = vec![1,2,3]; assert!(foo.at(0).replace(4) == Some(1)); assert!(foo == vec![4,2,3]); assert!(foo.at(3).replace(0) == None); assert!(foo == vec![4,2,3]); assert!(foo.at(1..=2).replace(vec![5,6,7]) == Some(vec![2,3])); assert!(foo == vec![4,5,6,7]); // faster but less flexible // VVVVVV assert!(foo.at(()).at(1..=2).at(0).replace(8) == Some(5)); assert!(foo == vec![4,8,6,7]);
Map accessors
Implemented for HashMap
and BTreeMap
:
map.at(&k).access(f)
is equivalent tomap.get_mut(&k).map(|v| f(v))
map.at( (k,v) ).access(f)
is equivalent toSome(f(map.entry(k).or_insert(v)))
map.at( (k,v,m) ).access(f)
is equivalent toSome(f(self.entry(k).and_modify(m).or_insert(v)))
let mut hm = HashMap::<usize, usize>::new(); hm.at( (42, 1) ).touch(); let mut found = false; hm.at(&42).access(|x| { assert!(*x == 1); found = true; *x += 1; }); assert!(found); assert!(hm.get(&42) == Some(&2)); let mutator = |x: &mut _| { *x = 4; }; hm.at( (41, 3, &mutator) ).touch(); hm.at( (42, 3, &mutator) ).touch(); assert!(hm.get(&41) == Some(&3)); assert!(hm.get(&42) == Some(&4));
Set accessors
Implemented for HashSet<T>
and BTreeSet<T>
.
Semantics differ from the HashMap<T, ()>
and BTreeMap<T, ()>
implementations:
the Map
ones do not change the key, but the Set
ones do change.
Compare:
let mut map = HashMap::<String,()>::new(); let mut set = HashSet::<String>::new(); map.at( ("Hello".to_string(), ()) ).touch(); set.at( ("Hello".to_string(), ()) ).touch(); map.at("Hello").access(|()| { /* We can do nothing here with the string... */ }); set.at("Hello").access(|hello| { *hello = "world".to_string(); } ); assert!(set == vec!["world".to_string()].into_iter().collect());
Also a one-tuple accessor is available, allowing to chain insertions:
let mut set = HashSet::new(); set.at( (2,) ).at( (3,) ).at( (5,) ).at( (7,) ).touch(); assert!(set == vec![2,3,5,7].into_iter().collect());