use std::collections::{BTreeMap, HashMap};
use crate::{Error, Value};
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct Map(pub(crate) BTreeMap<Value, Value>);
impl Map {
#[must_use]
pub const fn new() -> Self {
Self(BTreeMap::new())
}
#[must_use]
pub const fn get_ref(&self) -> &BTreeMap<Value, Value> {
&self.0
}
pub fn get_mut(&mut self) -> &mut BTreeMap<Value, Value> {
&mut self.0
}
#[must_use]
pub fn into_inner(self) -> BTreeMap<Value, Value> {
self.0
}
pub fn from_pairs<K, V, I>(pairs: I) -> Self
where
K: Into<Value>,
V: Into<Value>,
I: IntoIterator<Item = (K, V)>,
{
Self(pairs.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
}
pub fn try_from_pairs<K, V, I>(pairs: I) -> Result<Self, Error>
where
K: Into<Value>,
V: Into<Value>,
I: IntoIterator<Item = (K, V)>,
{
let mut map = BTreeMap::new();
for (k, v) in pairs {
if map.insert(k.into(), v.into()).is_some() {
return Err(Error::NonDeterministic);
}
}
Ok(Self(map))
}
pub fn from_sequence<I>(items: I) -> Result<Self, Error>
where
I: IntoIterator<Item = Value>,
{
let mut iter = items.into_iter();
let mut map: BTreeMap<Value, Value> = BTreeMap::new();
while let Some(key) = iter.next() {
let value = iter.next().ok_or(Error::UnexpectedEof)?;
if let Some((last_key, _)) = map.last_key_value()
&& *last_key >= key
{
return Err(Error::NonDeterministic);
}
map.insert(key, value);
}
Ok(Self(map))
}
pub fn try_from_sequence<I, E>(items: I) -> Result<Self, E>
where
I: IntoIterator<Item = Result<Value, E>>,
E: From<Error>,
{
let mut iter = items.into_iter();
let mut map: BTreeMap<Value, Value> = BTreeMap::new();
while let Some(key) = iter.next() {
let key = key?;
let value = iter.next().ok_or(Error::UnexpectedEof)??;
if let Some((last_key, _)) = map.last_key_value()
&& *last_key >= key
{
return Err(Error::NonDeterministic.into());
}
map.insert(key, value);
}
Ok(Self(map))
}
}
impl From<BTreeMap<Value, Value>> for Map {
fn from(map: BTreeMap<Value, Value>) -> Self {
Map(map)
}
}
impl<K: Into<Value> + Copy, V: Into<Value> + Copy> From<&BTreeMap<K, V>> for Map {
fn from(map: &BTreeMap<K, V>) -> Self {
Map(map.iter().map(|(&k, &v)| (k.into(), v.into())).collect())
}
}
impl<K: Into<Value> + Copy, V: Into<Value> + Copy> From<&HashMap<K, V>> for Map {
fn from(map: &HashMap<K, V>) -> Self {
Map(map.iter().map(|(&k, &v)| (k.into(), v.into())).collect())
}
}
impl<K: Into<Value> + Copy, V: Into<Value> + Copy> From<&[(K, V)]> for Map {
fn from(slice: &[(K, V)]) -> Self {
Self(slice.iter().map(|&(k, v)| (k.into(), v.into())).collect())
}
}
impl<const N: usize, K: Into<Value>, V: Into<Value>> From<[(K, V); N]> for Map {
fn from(array: [(K, V); N]) -> Self {
Self(array.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
}
}
impl<K: Into<Value>, V: Into<Value>> From<Vec<(K, V)>> for Map {
fn from(vec: Vec<(K, V)>) -> Self {
Self(vec.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
}
}
impl<K: Into<Value>, V: Into<Value>> From<Box<[(K, V)]>> for Map {
fn from(boxed: Box<[(K, V)]>) -> Self {
Self(
Vec::from(boxed)
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect(),
)
}
}
impl From<()> for Map {
fn from(_: ()) -> Self {
Self(BTreeMap::new())
}
}