use std::collections::{BTreeMap, HashMap};
use crate::{Error, Value};
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct Map<'a>(pub(crate) BTreeMap<Value<'a>, Value<'a>>);
impl<'a> Map<'a> {
#[must_use]
pub const fn new() -> Self {
Self(BTreeMap::new())
}
#[must_use]
pub const fn get_ref(&self) -> &BTreeMap<Value<'a>, Value<'a>> {
&self.0
}
pub const fn get_mut(&mut self) -> &mut BTreeMap<Value<'a>, Value<'a>> {
&mut self.0
}
#[must_use]
pub fn into_inner(self) -> BTreeMap<Value<'a>, Value<'a>> {
self.0
}
pub fn from_pairs<K, V, I>(pairs: I) -> Self
where
K: Into<Value<'a>>,
V: Into<Value<'a>>,
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<'a>>,
V: Into<Value<'a>>,
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<'a>>,
{
let mut iter = items.into_iter();
let mut map: BTreeMap<Value<'a>, Value<'a>> = 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<'a>, E>>,
E: From<Error>,
{
let mut iter = items.into_iter();
let mut map: BTreeMap<Value<'a>, Value<'a>> = 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<'a> From<BTreeMap<Value<'a>, Value<'a>>> for Map<'a> {
fn from(map: BTreeMap<Value<'a>, Value<'a>>) -> Self {
Map(map)
}
}
impl<'a, K: Into<Value<'a>> + Copy, V: Into<Value<'a>> + Copy> From<&BTreeMap<K, V>> for Map<'a> {
fn from(map: &BTreeMap<K, V>) -> Self {
Map(map.iter().map(|(&k, &v)| (k.into(), v.into())).collect())
}
}
impl<'a, K: Into<Value<'a>> + Copy, V: Into<Value<'a>> + Copy> From<&HashMap<K, V>> for Map<'a> {
fn from(map: &HashMap<K, V>) -> Self {
Map(map.iter().map(|(&k, &v)| (k.into(), v.into())).collect())
}
}
impl<'a, K: Into<Value<'a>> + Copy, V: Into<Value<'a>> + Copy> From<&[(K, V)]> for Map<'a> {
fn from(slice: &[(K, V)]) -> Self {
Self(slice.iter().map(|&(k, v)| (k.into(), v.into())).collect())
}
}
impl<'a, const N: usize, K: Into<Value<'a>>, V: Into<Value<'a>>> From<[(K, V); N]> for Map<'a> {
fn from(array: [(K, V); N]) -> Self {
Self(array.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
}
}
impl<'a, K: Into<Value<'a>>, V: Into<Value<'a>>> From<Vec<(K, V)>> for Map<'a> {
fn from(vec: Vec<(K, V)>) -> Self {
Self(vec.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
}
}
impl<'a, K: Into<Value<'a>>, V: Into<Value<'a>>> From<Box<[(K, V)]>> for Map<'a> {
fn from(boxed: Box<[(K, V)]>) -> Self {
Self(
Vec::from(boxed)
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect(),
)
}
}
impl<'a> From<()> for Map<'a> {
fn from(_: ()) -> Self {
Self(BTreeMap::new())
}
}