use std::iter::FromIterator;
use std::vec::IntoIter;
use super::Value;
#[derive(Debug, Clone, PartialEq)]
pub struct Object<S> {
key_value_list: Vec<(String, Value<S>)>,
}
impl<S> Object<S> {
pub fn with_capacity(size: usize) -> Self {
Object {
key_value_list: Vec::with_capacity(size),
}
}
pub fn add_field<K>(&mut self, k: K, value: Value<S>) -> Option<Value<S>>
where
K: Into<String>,
for<'a> &'a str: PartialEq<K>,
{
if let Some(item) = self
.key_value_list
.iter_mut()
.find(|&&mut (ref key, _)| (key as &str) == k)
{
return Some(::std::mem::replace(&mut item.1, value));
}
self.key_value_list.push((k.into(), value));
None
}
pub fn contains_field<K>(&self, f: K) -> bool
where
for<'a> &'a str: PartialEq<K>,
{
self.key_value_list
.iter()
.any(|&(ref key, _)| (key as &str) == f)
}
pub fn iter(&self) -> FieldIter<S> {
FieldIter {
inner: self.key_value_list.iter(),
}
}
pub fn iter_mut(&mut self) -> FieldIterMut<S> {
FieldIterMut {
inner: self.key_value_list.iter_mut(),
}
}
pub fn field_count(&self) -> usize {
self.key_value_list.len()
}
pub fn get_field_value<K>(&self, key: K) -> Option<&Value<S>>
where
for<'a> &'a str: PartialEq<K>,
{
self.key_value_list
.iter()
.find(|&&(ref k, _)| (k as &str) == key)
.map(|&(_, ref value)| value)
}
}
impl<S> IntoIterator for Object<S> {
type Item = (String, Value<S>);
type IntoIter = IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.key_value_list.into_iter()
}
}
impl<S> From<Object<S>> for Value<S> {
fn from(o: Object<S>) -> Self {
Value::Object(o)
}
}
impl<K, S> FromIterator<(K, Value<S>)> for Object<S>
where
K: Into<String>,
for<'a> &'a str: PartialEq<K>,
{
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = (K, Value<S>)>,
{
let iter = iter.into_iter();
let mut ret = Self {
key_value_list: Vec::with_capacity(iter.size_hint().0),
};
for (k, v) in iter {
ret.add_field(k, v);
}
ret
}
}
#[doc(hidden)]
pub struct FieldIter<'a, S: 'a> {
inner: ::std::slice::Iter<'a, (String, Value<S>)>,
}
impl<'a, S> Iterator for FieldIter<'a, S> {
type Item = &'a (String, Value<S>);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
#[doc(hidden)]
pub struct FieldIterMut<'a, S: 'a> {
inner: ::std::slice::IterMut<'a, (String, Value<S>)>,
}
impl<'a, S> Iterator for FieldIterMut<'a, S> {
type Item = &'a mut (String, Value<S>);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}