#![allow(clippy::useless_conversion)]
#![allow(clippy::useless_asref)]
use crate::{
Value,
json::key::Key,
json::value::{Element, Property},
};
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
pub struct ObjectAsVec<'ctx, P: Property, E: Element>(
pub(crate) Vec<(Key<'ctx, P>, Value<'ctx, P, E>)>,
);
impl<'ctx, P: Property, E: Element> From<Vec<(Key<'ctx, P>, Value<'ctx, P, E>)>>
for ObjectAsVec<'ctx, P, E>
{
fn from(vec: Vec<(Key<'ctx, P>, Value<'ctx, P, E>)>) -> Self {
ObjectAsVec(vec)
}
}
impl<'ctx, P: Property, E: Element> FromIterator<(Key<'ctx, P>, Value<'ctx, P, E>)>
for ObjectAsVec<'ctx, P, E>
{
fn from_iter<T: IntoIterator<Item = (Key<'ctx, P>, Value<'ctx, P, E>)>>(iter: T) -> Self {
Self(iter.into_iter().collect())
}
}
impl<'ctx, P: Property, E: Element> ObjectAsVec<'ctx, P, E> {
pub fn new() -> Self {
Self(Vec::new())
}
pub fn with_capacity(capacity: usize) -> Self {
Self(Vec::with_capacity(capacity))
}
#[inline]
pub fn as_vec(&self) -> &Vec<(Key<'ctx, P>, Value<'ctx, P, E>)> {
&self.0
}
#[inline]
pub fn as_mut_vec(&mut self) -> &mut Vec<(Key<'ctx, P>, Value<'ctx, P, E>)> {
&mut self.0
}
#[inline]
pub fn into_vec(self) -> Vec<(Key<'ctx, P>, Value<'ctx, P, E>)> {
self.0
}
#[inline]
pub fn get(&self, key: &Key<'_, P>) -> Option<&Value<'ctx, P, E>> {
self.0
.iter()
.find_map(|(k, v)| if k == key { Some(v) } else { None })
}
#[inline]
pub fn get_ignore_case(&self, key: &str) -> Option<&Value<'ctx, P, E>> {
self.0.iter().find_map(|(k, v)| {
if k.to_string().eq_ignore_ascii_case(key) {
Some(v)
} else {
None
}
})
}
#[inline]
pub fn get_mut(&mut self, key: &Key<'ctx, P>) -> Option<&mut Value<'ctx, P, E>> {
self.0
.iter_mut()
.find_map(move |(k, v)| if k == key { Some(v) } else { None })
}
#[inline]
pub fn get_key_value(&self, key: &Key<'_, P>) -> Option<(&Key<'_, P>, &Value<'ctx, P, E>)> {
self.0
.iter()
.find_map(|(k, v)| if k == key { Some((k, v)) } else { None })
}
#[inline]
pub fn iter(&self) -> impl Iterator<Item = (&Key<'ctx, P>, &Value<'ctx, P, E>)> {
self.0.iter().map(|(k, v)| (k, v))
}
#[inline]
pub fn iter_mut(
&mut self,
) -> impl Iterator<Item = (&mut Key<'ctx, P>, &mut Value<'ctx, P, E>)> {
self.0.iter_mut().map(|(k, v)| (k, v))
}
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline]
pub fn keys(&self) -> impl Iterator<Item = &Key<'ctx, P>> {
self.0.iter().map(|(k, _)| k)
}
#[inline]
pub fn values(&self) -> impl Iterator<Item = &Value<'ctx, P, E>> {
self.0.iter().map(|(_, v)| v)
}
#[inline]
pub fn contains_key(&self, key: &Key<'ctx, P>) -> bool {
self.0.iter().any(|(k, _)| k == key)
}
#[inline]
pub fn contains_key_value(&self, key: &Key<'ctx, P>, value: &Value<'ctx, P, E>) -> bool {
self.0.iter().any(|(k, v)| k == key && v == value)
}
#[inline]
pub fn contains_any_key(&self, keys: &[Key<'ctx, P>]) -> bool {
self.0.iter().any(|(k, _)| keys.contains(k))
}
pub fn remove(&mut self, key: &Key<'ctx, P>) -> Option<Value<'ctx, P, E>> {
if let Some(pos) = self.0.iter().position(|(k, _)| k == key) {
Some(self.0.swap_remove(pos).1)
} else {
None
}
}
#[inline]
pub fn insert(
&mut self,
key: impl Into<Key<'ctx, P>>,
value: impl Into<Value<'ctx, P, E>>,
) -> Option<Value<'ctx, P, E>> {
let key = key.into();
for (k, v) in &mut self.0 {
if k == &key {
return Some(std::mem::replace(v, value.into()));
}
}
self.0.push((key.into(), value.into()));
None
}
#[inline]
pub fn insert_or_get_mut(
&mut self,
key: impl Into<Key<'ctx, P>>,
value: impl Into<Value<'ctx, P, E>>,
) -> &mut Value<'ctx, P, E> {
let key = key.into();
if let Some(pos) = self.0.iter_mut().position(|(k, _)| *k == key) {
&mut self.0[pos].1
} else {
self.0.push((key, value.into()));
&mut self.0.last_mut().unwrap().1
}
}
#[inline]
pub fn insert_unchecked(
&mut self,
key: impl Into<Key<'ctx, P>>,
value: impl Into<Value<'ctx, P, E>>,
) {
self.0.push((key.into(), value.into()));
}
#[inline]
pub fn with_key_value(
mut self,
key: impl Into<Key<'ctx, P>>,
value: impl Into<Value<'ctx, P, E>>,
) -> Self {
self.insert_unchecked(key, value);
self
}
pub fn insert_named(&mut self, key: Option<String>, value: Value<'ctx, P, E>) -> String {
let len = self.0.len();
let mut key = key.unwrap_or_else(|| format!("k{}", len + 1));
if self.contains_key(&Key::Borrowed(key.as_str())) {
key = format!("{}-{}", key, len + 1);
}
self.0.push((Key::Owned(key.clone()), value));
key
}
#[inline]
pub fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = (Key<'ctx, P>, Value<'ctx, P, E>)>,
{
self.0.extend(iter);
}
#[inline]
pub fn insert_unchecked_and_get_mut(
&mut self,
key: impl Into<Key<'ctx, P>>,
value: impl Into<Value<'ctx, P, E>>,
) -> &mut Value<'ctx, P, E> {
let key = key.into();
self.0.push((key, value.into()));
let idx = self.0.len() - 1;
&mut self.0[idx].1
}
}
impl<'ctx, P: Property, E: Element<Property = P>> ObjectAsVec<'ctx, P, E> {
pub fn into_expanded_boolean_set(self) -> impl Iterator<Item = Key<'ctx, P>> {
self.into_vec()
.into_iter()
.filter_map(|(key, value)| value.as_bool().filter(|&b| b).map(|_| key))
}
}
impl<'ctx, P: Property, E: Element> From<ObjectAsVec<'ctx, P, E>>
for serde_json::Map<String, serde_json::Value>
{
fn from(val: ObjectAsVec<'ctx, P, E>) -> Self {
val.iter()
.map(|(key, val)| (key.to_string().into_owned(), val.into()))
.collect()
}
}
impl<'ctx, P: Property, E: Element> From<&ObjectAsVec<'ctx, P, E>>
for serde_json::Map<String, serde_json::Value>
{
fn from(val: &ObjectAsVec<'ctx, P, E>) -> Self {
val.iter()
.map(|(key, val)| (key.to_string().into_owned(), val.into()))
.collect()
}
}