use {
core::{
borrow::Borrow,
hash::Hash,
},
alloc::boxed::Box,
crate::{Json, MapKind, ObjectKey},
};
pub type BTreeMap = alloc::collections::BTreeMap<ObjectKey, Json>;
#[cfg(feature="std")]
#[doc(cfg(feature="std"))]
pub type HashMap = std::collections::HashMap<ObjectKey, Json>;
#[derive(Debug, Clone)]
pub enum Map {
BTreeMap(BTreeMap),
#[cfg(feature="std")]
#[doc(cfg(feature="std"))]
HashMap(HashMap),
}
impl Map {
pub fn new(kind: MapKind) -> Self {
match kind {
MapKind::BTreeMap => Self::BTreeMap(BTreeMap::new()),
#[cfg(feature="std")]
MapKind::HashMap => Self::HashMap(HashMap::new()),
}
}
pub fn with_capacity(kind: MapKind, capacity: usize) -> Self {
match kind {
MapKind::BTreeMap => {
let _ = capacity;
Self::BTreeMap(BTreeMap::new())
},
#[cfg(feature="std")]
MapKind::HashMap => Self::HashMap(HashMap::with_capacity(capacity)),
}
}
pub fn is_empty(&self) -> bool {
match self {
Self::BTreeMap(map) => map.is_empty(),
#[cfg(feature="std")]
Self::HashMap(map) => map.is_empty(),
}
}
pub fn len(&self) -> usize {
match self {
Self::BTreeMap(map) => map.len(),
#[cfg(feature="std")]
Self::HashMap(map) => map.len(),
}
}
pub fn insert<K, V>(&mut self, key: K, value: V) -> Option<Json> where K: Into<ObjectKey>, V: Into<Json> {
let key = key.into();
let value = value.into();
match self {
Self::BTreeMap(map) => map.insert(key, value),
#[cfg(feature="std")]
Self::HashMap(map) => map.insert(key, value),
}
}
pub (crate) fn get<K>(&self, key: &K) -> Option<&Json> where ObjectKey: Borrow<K>, K: Ord + Hash + Eq + ?Sized {
match self {
Self::BTreeMap(map) => map.get(key),
#[cfg(feature="std")]
Self::HashMap(map) => map.get(key),
}
}
pub (crate) fn get_mut<K>(&mut self, key: &K) -> Option<&mut Json> where ObjectKey: Borrow<K>, K: Ord + Hash + Eq + ?Sized {
match self {
Self::BTreeMap(map) => map.get_mut(key),
#[cfg(feature="std")]
Self::HashMap(map) => map.get_mut(key),
}
}
pub (crate) fn remove<K>(&mut self, key: &K) -> Option<Json> where ObjectKey: Borrow<K>, K: Ord + Hash + Eq + ?Sized {
match self {
Self::BTreeMap(map) => map.remove(key),
#[cfg(feature="std")]
Self::HashMap(map) => map.remove(key),
}
}
pub fn iter(&self) -> Box<dyn Iterator<Item=(&ObjectKey, &Json)> + '_> {
match self {
Self::BTreeMap(map) => Box::new(map.iter()),
#[cfg(feature="std")]
Self::HashMap(map) => Box::new(map.iter()),
}
}
pub fn into_iter(self) -> Box<dyn Iterator<Item=(ObjectKey, Json)>> {
match self {
Self::BTreeMap(map) => Box::new(map.into_iter()),
#[cfg(feature="std")]
Self::HashMap(map) => Box::new(map.into_iter()),
}
}
}
impl From<BTreeMap> for Map {
fn from(map: BTreeMap) -> Self {
Self::BTreeMap(map)
}
}
#[cfg(feature="std")]
#[doc(cfg(feature="std"))]
impl From<HashMap> for Map {
fn from(map: HashMap) -> Self {
Self::HashMap(map)
}
}
impl From<Map> for BTreeMap {
fn from(map: Map) -> Self {
match map {
Map::BTreeMap(map) => map,
#[cfg(feature="std")]
Map::HashMap(map) => map.into_iter().collect(),
}
}
}
#[cfg(feature="std")]
#[doc(cfg(feature="std"))]
impl From<Map> for HashMap {
fn from(map: Map) -> Self {
match map {
Map::BTreeMap(map) => map.into_iter().collect(),
Map::HashMap(map) => map,
}
}
}