use std::collections;
use std::hash::Hash;
use std::borrow::Borrow;
use value::Value;
#[derive(PartialEq, Clone, Debug)]
pub struct Map<K, V> {
map: MapImpl<K, V>,
}
type MapImpl<K, V> = collections::BTreeMap<K, V>;
impl Map<String, Value> {
#[inline]
pub fn new() -> Self {
Map { map: MapImpl::new() }
}
#[inline]
pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&Value>
where
String: Borrow<Q>,
Q: Ord + Eq + Hash,
{
self.map.get(key)
}
#[inline]
pub fn insert(&mut self, k: String, v: Value) -> Option<Value> {
self.map.insert(k, v)
}
pub fn entry<S>(&mut self, key: S) -> Entry
where
S: Into<String>,
{
use std::collections::btree_map::Entry as EntryImpl;
match self.map.entry(key.into()) {
EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant: vacant }),
EntryImpl::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied: occupied }),
}
}
}
impl<K, V> IntoIterator for Map<K, V> {
type Item = (K, V);
type IntoIter = collections::btree_map::IntoIter<K, V>;
fn into_iter(self) -> collections::btree_map::IntoIter<K, V> {
self.map.into_iter()
}
}
pub enum Entry<'a> {
Vacant(VacantEntry<'a>),
Occupied(OccupiedEntry<'a>),
}
pub struct VacantEntry<'a> {
vacant: VacantEntryImpl<'a>,
}
pub struct OccupiedEntry<'a> {
occupied: OccupiedEntryImpl<'a>,
}
type VacantEntryImpl<'a> = collections::btree_map::VacantEntry<'a, String, Value>;
type OccupiedEntryImpl<'a> = collections::btree_map::OccupiedEntry<'a, String, Value>;
impl<'a> Entry<'a> {
pub fn key(&self) -> &String {
match *self {
Entry::Vacant(ref e) => e.key(),
Entry::Occupied(ref e) => e.key(),
}
}
pub fn or_insert(self, default: Value) -> &'a mut Value {
match self {
Entry::Vacant(entry) => entry.insert(default),
Entry::Occupied(entry) => entry.into_mut(),
}
}
pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
where
F: FnOnce() -> Value,
{
match self {
Entry::Vacant(entry) => entry.insert(default()),
Entry::Occupied(entry) => entry.into_mut(),
}
}
}
impl<'a> VacantEntry<'a> {
#[inline]
pub fn key(&self) -> &String {
self.vacant.key()
}
#[inline]
pub fn insert(self, value: Value) -> &'a mut Value {
self.vacant.insert(value)
}
}
impl<'a> OccupiedEntry<'a> {
#[inline]
pub fn key(&self) -> &String {
self.occupied.key()
}
#[inline]
pub fn get(&self) -> &Value {
self.occupied.get()
}
#[inline]
pub fn get_mut(&mut self) -> &mut Value {
self.occupied.get_mut()
}
#[inline]
pub fn into_mut(self) -> &'a mut Value {
self.occupied.into_mut()
}
#[inline]
pub fn insert(&mut self, value: Value) -> Value {
self.occupied.insert(value)
}
#[inline]
pub fn remove(self) -> Value {
self.occupied.remove()
}
}