use indexmap::{map, IndexMap};
use std::{
fmt::{self, Debug},
iter::FromIterator,
ops,
};
use crate::Value;
pub struct Dictionary {
map: IndexMap<String, Value>,
}
impl Dictionary {
#[inline]
pub fn new() -> Self {
Dictionary {
map: IndexMap::new(),
}
}
#[inline]
pub fn clear(&mut self) {
self.map.clear()
}
#[inline]
pub fn get(&self, key: &str) -> Option<&Value> {
self.map.get(key)
}
#[inline]
pub fn contains_key(&self, key: &str) -> bool {
self.map.contains_key(key)
}
#[inline]
pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
self.map.get_mut(key)
}
#[inline]
pub fn insert(&mut self, k: String, v: Value) -> Option<Value> {
self.map.insert(k, v)
}
#[inline]
pub fn remove(&mut self, key: &str) -> Option<Value> {
self.map.remove(key)
}
#[cfg(any(
test,
feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
))]
pub fn entry<S>(&mut self, key: S) -> Entry
where
S: Into<String>,
{
match self.map.entry(key.into()) {
map::Entry::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }),
map::Entry::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }),
}
}
#[inline]
pub fn len(&self) -> usize {
self.map.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
#[inline]
pub fn iter(&self) -> Iter {
Iter {
iter: self.map.iter(),
}
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut {
IterMut {
iter: self.map.iter_mut(),
}
}
#[inline]
pub fn keys(&self) -> Keys {
Keys {
iter: self.map.keys(),
}
}
#[inline]
pub fn values(&self) -> Values {
Values {
iter: self.map.values(),
}
}
#[inline]
pub fn values_mut(&mut self) -> ValuesMut {
ValuesMut {
iter: self.map.values_mut(),
}
}
}
impl Default for Dictionary {
#[inline]
fn default() -> Self {
Dictionary {
map: Default::default(),
}
}
}
impl Clone for Dictionary {
#[inline]
fn clone(&self) -> Self {
Dictionary {
map: self.map.clone(),
}
}
}
impl PartialEq for Dictionary {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.map.eq(&other.map)
}
}
impl<'a> ops::Index<&'a str> for Dictionary {
type Output = Value;
fn index(&self, index: &str) -> &Value {
self.map.index(index)
}
}
impl<'a> ops::IndexMut<&'a str> for Dictionary {
fn index_mut(&mut self, index: &str) -> &mut Value {
self.map.get_mut(index).expect("no entry found for key")
}
}
impl Debug for Dictionary {
#[inline]
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.map.fmt(formatter)
}
}
impl FromIterator<(String, Value)> for Dictionary {
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = (String, Value)>,
{
Dictionary {
map: FromIterator::from_iter(iter),
}
}
}
impl Extend<(String, Value)> for Dictionary {
fn extend<T>(&mut self, iter: T)
where
T: IntoIterator<Item = (String, Value)>,
{
self.map.extend(iter);
}
}
macro_rules! delegate_iterator {
(($name:ident $($generics:tt)*) => $item:ty) => {
impl $($generics)* Iterator for $name $($generics)* {
type Item = $item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl $($generics)* ExactSizeIterator for $name $($generics)* {
#[inline]
fn len(&self) -> usize {
self.iter.len()
}
}
}
}
#[cfg(any(
test,
feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
))]
pub enum Entry<'a> {
Vacant(VacantEntry<'a>),
Occupied(OccupiedEntry<'a>),
}
#[cfg(any(
test,
feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
))]
pub struct VacantEntry<'a> {
vacant: map::VacantEntry<'a, String, Value>,
}
#[cfg(any(
test,
feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
))]
pub struct OccupiedEntry<'a> {
occupied: map::OccupiedEntry<'a, String, Value>,
}
#[cfg(any(
test,
feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
))]
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(),
}
}
}
#[cfg(any(
test,
feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
))]
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)
}
}
#[cfg(any(
test,
feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
))]
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()
}
}
impl<'a> IntoIterator for &'a Dictionary {
type Item = (&'a String, &'a Value);
type IntoIter = Iter<'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
Iter {
iter: self.map.iter(),
}
}
}
pub struct Iter<'a> {
iter: IterImpl<'a>,
}
type IterImpl<'a> = map::Iter<'a, String, Value>;
delegate_iterator!((Iter<'a>) => (&'a String, &'a Value));
impl<'a> IntoIterator for &'a mut Dictionary {
type Item = (&'a String, &'a mut Value);
type IntoIter = IterMut<'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IterMut {
iter: self.map.iter_mut(),
}
}
}
pub struct IterMut<'a> {
iter: map::IterMut<'a, String, Value>,
}
delegate_iterator!((IterMut<'a>) => (&'a String, &'a mut Value));
impl IntoIterator for Dictionary {
type Item = (String, Value);
type IntoIter = IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IntoIter {
iter: self.map.into_iter(),
}
}
}
pub struct IntoIter {
iter: map::IntoIter<String, Value>,
}
delegate_iterator!((IntoIter) => (String, Value));
pub struct Keys<'a> {
iter: map::Keys<'a, String, Value>,
}
delegate_iterator!((Keys<'a>) => &'a String);
pub struct Values<'a> {
iter: map::Values<'a, String, Value>,
}
delegate_iterator!((Values<'a>) => &'a Value);
pub struct ValuesMut<'a> {
iter: map::ValuesMut<'a, String, Value>,
}
delegate_iterator!((ValuesMut<'a>) => &'a mut Value);