MkeyMap API changes

This commit is contained in:
Alena Yuryeva 2018-07-19 17:27:25 +03:00 committed by Kevin K
parent 3efcf3ae03
commit 7faf6c7721
No known key found for this signature in database
GPG key ID: 2E39D46AABC94DDD

View file

@ -1,12 +1,12 @@
#![feature(nll)] #![feature(nll)]
use build::Arg;
use std::collections::hash_map; use std::collections::hash_map;
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::ffi::OsStr; use std::ffi::OsStr;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::slice; use std::slice;
use build::Arg;
// ! rustdoc // ! rustdoc
#[derive(Default, PartialEq, Debug)] #[derive(Default, PartialEq, Debug)]
@ -27,9 +27,7 @@ pub enum KeyType<'a> {
} }
impl<'a, 'b> MKeyMap<'a, 'b> { impl<'a, 'b> MKeyMap<'a, 'b> {
pub fn new() -> Self { pub fn new() -> Self { MKeyMap::default() }
MKeyMap::default()
}
//TODO ::from(x), ::with_capacity(n) etc //TODO ::from(x), ::with_capacity(n) etc
//? set theory ops? //? set theory ops?
@ -67,6 +65,8 @@ impl<'a, 'b> MKeyMap<'a, 'b> {
set set
}); });
} }
index
} }
//TODO ::push_many([x, y]) //TODO ::push_many([x, y])
@ -89,37 +89,31 @@ impl<'a, 'b> MKeyMap<'a, 'b> {
self.keys.insert(key, index); self.keys.insert(key, index);
} }
pub fn get(&self, key: KeyType<'a>) -> &Arg<'a, 'b> { pub fn get(&self, key: KeyType<'a>) -> Option<&Arg<'a, 'b>> {
self.keys self.keys
.get(&key) .get(&key)
.and_then(|&idx| self.value_index.get(idx)) .and_then(|&idx| self.value_index.get(idx))
.expect(&format!("No entry for the key: {:?}", key))
} }
//TODO ::get_first([KeyA, KeyB]) //TODO ::get_first([KeyA, KeyB])
pub fn get_mut(&mut self, key: KeyType<'a>) -> &mut Arg<'a, 'b> { pub fn get_mut(&mut self, key: KeyType<'a>) -> Option<&mut Arg<'a, 'b>> {
let idx = *self if let Some(&idx) = self
.keys .keys
.get(&key) .get(&key) {
.expect(&format!("No entry for the key: {:?}", key)); self.value_index.get_mut(idx)
} else {
self.value_index.get_mut(idx).unwrap() None
}
} }
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool { self.keys.is_empty() && self.values.is_empty() }
self.keys.is_empty() && self.values.is_empty()
}
pub fn remove(&mut self, key: KeyType) -> Option<Arg> { pub fn remove(&mut self, key: KeyType) -> Option<Arg> { unimplemented!() }
unimplemented!()
}
//TODO ::remove_many([KeyA, KeyB]) //TODO ::remove_many([KeyA, KeyB])
//? probably shouldn't add a possibility for removal? //? probably shouldn't add a possibility for removal?
//? or remove by replacement by some dummy object, so the order is preserved //? or remove by replacement by some dummy object, so the order is preserved
pub fn remove_key(&mut self, key: KeyType) { pub fn remove_key(&mut self, key: KeyType) { unimplemented!() }
unimplemented!()
}
//TODO ::remove_keys([KeyA, KeyB]) //TODO ::remove_keys([KeyA, KeyB])
pub fn keys(&'a self) -> Keys<'a, usize> { pub fn keys(&'a self) -> Keys<'a, usize> {
@ -139,8 +133,16 @@ impl<'a, 'b> MKeyMap<'a, 'b> {
iter: self.value_index.iter_mut(), iter: self.value_index.iter_mut(),
} }
} }
pub fn iter(&self) -> Iter {
Iter {
map: self,
keys: self.keys(),
}
}
} }
//TODO remove generics
pub struct Keys<'a, V: 'a> { pub struct Keys<'a, V: 'a> {
iter: hash_map::Keys<'a, KeyType<'a>, V>, iter: hash_map::Keys<'a, KeyType<'a>, V>,
} }
@ -148,9 +150,7 @@ pub struct Keys<'a, V: 'a> {
impl<'a, V> Iterator for Keys<'a, V> { impl<'a, V> Iterator for Keys<'a, V> {
type Item = &'a KeyType<'a>; type Item = &'a KeyType<'a>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> { self.iter.next() }
self.iter.next()
}
} }
pub struct Values<'a, V: 'a> { pub struct Values<'a, V: 'a> {
@ -160,9 +160,7 @@ pub struct Values<'a, V: 'a> {
impl<'a, V> Iterator for Values<'a, V> { impl<'a, V> Iterator for Values<'a, V> {
type Item = &'a V; type Item = &'a V;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> { self.iter.next() }
self.iter.next()
}
} }
pub struct ValuesMut<'a, V: 'a> { pub struct ValuesMut<'a, V: 'a> {
@ -170,18 +168,36 @@ pub struct ValuesMut<'a, V: 'a> {
} }
impl<'a, V> Iterator for ValuesMut<'a, V> { impl<'a, V> Iterator for ValuesMut<'a, V> {
type Item = &'a V; type Item = &'a mut V;
fn next(&mut self) -> Option<Self::Item> { self.iter.next() }
}
pub struct Iter<'a, 'b, 'c> where
'a: 'b,
'b: 'c {
map: &'c MKeyMap<'a, 'b>,
keys: Keys<'c, usize>,
}
impl <'a, 'b, 'c> Iterator for Iter<'a, 'b, 'c>
{
type Item = (&'c KeyType<'a>, &'c Arg<'a, 'b>);
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
self.iter.next() if let Some(key) = self.keys.next() {
Some((key, self.map.get(key.clone()).unwrap()))
} else {
None
}
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use self::KeyType::*;
use super::*; use super::*;
use std::ffi::OsStr; use std::ffi::OsStr;
use self::KeyType::*;
#[test] #[test]
fn get_some_value() { fn get_some_value() {
@ -191,10 +207,7 @@ mod tests {
map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1")); map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
} }
assert_eq!( assert_eq!(map.get(Long(&OsStr::new("One"))), &Arg::with_name("Value1"));
map.get(Long(&OsStr::new("One"))),
&Arg::with_name("Value1")
);
} }
#[test] #[test]