use crate::serde::byte_keys_as_strings;
use crate::value::Value;
use crate::value::equivalent::Equivalent;
use crate::value::keys::Keys;
use crate::value::meta::Meta;
use crate::value::print::Print;
use crate::value::tracer::Tracer;
use indexmap::IndexMap;
use indexmap::map::Entry;
use serde::Deserialize;
use serde::Serialize;
#[derive(Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Map {
#[serde(default, skip_serializing_if = "Tracer::is_empty")]
pub(crate) tracer: Tracer,
#[serde(default, skip_serializing_if = "Meta::is_empty")]
pub(crate) meta: Meta,
#[serde(with = "byte_keys_as_strings")]
pub(crate) data: IndexMap<Vec<u8>, Value, ahash::RandomState>,
}
impl core::fmt::Debug for Map {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Map")
.field("tracer", &self.tracer)
.field("meta", &self.meta)
.field("data", &DebugMap(&self.data))
.finish()
}
}
impl core::fmt::Display for Map {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(&String::from_utf8_lossy(&self.clone().print_syntax()))
}
}
struct DebugMap<'a>(&'a IndexMap<Vec<u8>, Value, ahash::RandomState>);
impl core::hash::Hash for Map {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
for (k, v) in &self.data {
k.hash(state);
v.hash(state);
}
}
}
impl core::fmt::Debug for DebugMap<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_map()
.entries(self.0.iter().map(|(k, v)| (String::from_utf8_lossy(k), v)))
.finish()
}
}
impl<K: Into<Vec<u8>>, V: Into<Value>> From<(K, V)> for Map {
fn from(value: (K, V)) -> Self {
[value].into_iter().collect()
}
}
impl<K: Into<Vec<u8>>, V: Into<Value>> FromIterator<(K, V)> for Map {
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
Self {
data: iter
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect(),
..Default::default()
}
}
}
impl FromIterator<Map> for Map {
fn from_iter<T: IntoIterator<Item = Map>>(iter: T) -> Self {
Self {
data: iter.into_iter().flat_map(Map::into_iter).collect(),
..Default::default()
}
}
}
impl FromIterator<(Keys, Value)> for Map {
fn from_iter<T: IntoIterator<Item = (Keys, Value)>>(iter: T) -> Self {
Self {
data: iter.into_iter().map(|(k, v)| (k.join(), v)).collect(),
..Default::default()
}
}
}
impl IntoIterator for Map {
type Item = (Vec<u8>, Value);
type IntoIter = <IndexMap<Vec<u8>, Value> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}
impl Map {
pub(crate) fn trace<T: Into<Tracer>>(&mut self, tracer: T) {
self.tracer.trace(tracer);
}
pub(crate) fn tracer(&self) -> &Tracer {
&self.tracer
}
pub fn with<K: Into<Vec<u8>>, V: Into<Value>>(mut self, key: K, value: V) -> Self {
self.fold_key(key.into(), value.into());
self
}
pub fn with_fold(mut self, other: Self) -> Self {
self.fold(other);
self
}
pub fn contains_key<K: AsRef<[u8]>>(&self, key: K) -> bool {
self.data.contains_key(key.as_ref())
}
pub fn contains_value(&self, value: &Value) -> bool {
self.data.iter().any(|(_, v)| v.equivalent(value))
}
pub fn iter(&self) -> impl Iterator<Item = (&Vec<u8>, &Value)> {
self.data.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&Vec<u8>, &mut Value)> {
self.data.iter_mut()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn clear(mut self) -> Self {
self.data = IndexMap::default();
self
}
pub fn join(self) -> Vec<u8> {
self.data.into_values().flat_map(Value::join).collect()
}
pub fn sort(&mut self) {
self.data.sort_keys();
}
pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Option<&Value> {
self.data.get(key.as_ref())
}
pub fn get_mut<'a>(&'a mut self, key: &[u8]) -> Option<&'a mut Value> {
self.data.get_mut(key)
}
pub fn shift_remove<K: AsRef<[u8]>>(&mut self, key: K) -> Option<Value> {
self.data.shift_remove(key.as_ref())
}
pub fn swap_remove<K: AsRef<[u8]>>(&mut self, key: K) -> Option<Value> {
self.data.swap_remove(key.as_ref())
}
#[doc(hidden)]
pub fn fold(&mut self, other: Self) {
for (key, value) in other.data {
match self.data.entry(key.clone()) {
Entry::Occupied(mut e) => {
e.get_mut().fold(value);
}
Entry::Vacant(_) => match other.meta.get(b"internal-insert") {
Some(b"prepend") => self.insert_prepend(key, value),
_ => self.insert_append(key, value),
},
}
}
}
#[doc(hidden)]
pub fn fold_key<K: Into<Vec<u8>>, V: Into<Value>>(&mut self, key: K, value: V) {
let key = key.into();
let value = value.into();
match self.data.entry(key.clone()) {
Entry::Occupied(mut e) => e.get_mut().fold(value),
Entry::Vacant(_) => drop(self.insert(key, value)),
}
}
pub fn insert<K: Into<Vec<u8>>, V: Into<Value>>(&mut self, key: K, value: V) {
let key = key.into();
let value = value.into();
match value.meta().get(b"internal-insert") {
Some(b"prepend") => self.insert_prepend(key, value),
_ => self.insert_append(key, value),
}
}
fn insert_append<K: Into<Vec<u8>>, V: Into<Value>>(&mut self, key: K, value: V) {
self.data.insert(key.into(), value.into());
}
fn insert_prepend<K: Into<Vec<u8>>, V: Into<Value>>(&mut self, key: K, value: V) {
self.data.insert_before(0, key.into(), value.into());
}
}