import_stdlib!();
use super::varint::{EncodeVarInt, MajorType};
use crate::{CBOR, CBORCase, Error, Result};
#[derive(Clone)]
pub struct Map(BTreeMap<MapKey, MapValue>);
impl Map {
pub fn new() -> Self { Map(BTreeMap::new()) }
pub fn len(&self) -> usize { self.0.len() }
pub fn is_empty(&self) -> bool { self.0.is_empty() }
pub fn iter(&self) -> MapIter<'_> { MapIter::new(self.0.values()) }
pub fn insert(&mut self, key: impl Into<CBOR>, value: impl Into<CBOR>) {
let key = key.into();
let value = value.into();
self.0
.insert(MapKey::new(key.to_cbor_data()), MapValue::new(key, value));
}
pub(crate) fn insert_next(&mut self, key: CBOR, value: CBOR) -> Result<()> {
match self.0.last_key_value() {
None => {
self.insert(key, value);
Ok(())
}
Some(entry) => {
let new_key = MapKey::new(key.to_cbor_data());
if self.0.contains_key(&new_key) {
return Err(Error::DuplicateMapKey);
}
if entry.0 >= &new_key {
return Err(Error::MisorderedMapKey);
}
self.0.insert(new_key, MapValue::new(key, value));
Ok(())
}
}
}
pub fn get<K, V>(&self, key: K) -> Option<V>
where
K: Into<CBOR>,
V: TryFrom<CBOR>,
{
match self.0.get(&MapKey::new(key.into().to_cbor_data())) {
Some(value) => V::try_from(value.value.clone()).ok(),
None => None,
}
}
pub fn contains_key<K>(&self, key: K) -> bool
where
K: Into<CBOR>,
{
self.0.contains_key(&MapKey::new(key.into().to_cbor_data()))
}
pub fn extract<K, V>(&self, key: K) -> Result<V>
where
K: Into<CBOR>,
V: TryFrom<CBOR>,
{
match self.get(key) {
Some(value) => Ok(value),
None => Err(Error::MissingMapKey),
}
}
}
impl Default for Map {
fn default() -> Self { Self::new() }
}
impl PartialEq for Map {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl Eq for Map {
fn assert_receiver_is_total_eq(&self) {}
}
impl hash::Hash for Map {
fn hash<H: hash::Hasher>(&self, state: &mut H) { self.0.hash(state); }
}
impl Map {
pub fn cbor_data(&self) -> Vec<u8> {
let pairs: Vec<(Vec<u8>, Vec<u8>)> = self
.0
.iter()
.map(|x| {
let a: Vec<u8> = x.0.0.to_owned();
let cbor: &CBOR = &x.1.value;
let b: Vec<u8> = cbor.to_cbor_data();
(a, b)
})
.collect();
let mut buf = pairs.len().encode_varint(MajorType::Map);
for pair in pairs {
buf.extend(pair.0);
buf.extend(pair.1);
}
buf
}
}
impl From<Map> for CBOR {
fn from(value: Map) -> Self { CBORCase::Map(value.clone()).into() }
}
impl From<&Map> for CBOR {
fn from(value: &Map) -> Self { value.clone().into() }
}
impl fmt::Debug for Map {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.0)
}
}
#[derive(Debug)]
pub struct MapIter<'a>(BTreeMapValues<'a, MapKey, MapValue>);
impl<'a> MapIter<'a> {
fn new(values: BTreeMapValues<'a, MapKey, MapValue>) -> MapIter<'a> {
MapIter(values)
}
}
impl<'a> Iterator for MapIter<'a> {
type Item = (&'a CBOR, &'a CBOR);
fn next(&mut self) -> Option<Self::Item> {
let entry = self.0.next()?;
Some((&entry.key, &entry.value))
}
}
#[derive(Clone, Eq)]
struct MapValue {
key: CBOR,
value: CBOR,
}
impl MapValue {
fn new(key: CBOR, value: CBOR) -> MapValue { MapValue { key, value } }
}
impl PartialEq for MapValue {
fn eq(&self, other: &Self) -> bool {
self.key == other.key && self.value == other.value
}
}
impl hash::Hash for MapValue {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.key.hash(state);
self.value.hash(state);
}
}
impl fmt::Debug for MapValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("({:?}, {:?})", self.key, self.value))
}
}
#[derive(Clone)]
struct MapKey(Vec<u8>);
impl MapKey {
fn new(key_data: Vec<u8>) -> MapKey { MapKey(key_data) }
}
impl PartialEq for MapKey {
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
impl Eq for MapKey {
fn assert_receiver_is_total_eq(&self) {}
}
impl hash::Hash for MapKey {
fn hash<H: hash::Hasher>(&self, state: &mut H) { self.0.hash(state); }
}
impl PartialOrd for MapKey {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for MapKey {
fn cmp(&self, other: &Self) -> cmp::Ordering { self.0.cmp(&other.0) }
}
impl fmt::Debug for MapKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("0x{}", hex::encode(&self.0)))
}
}
impl<T, K, V> From<T> for Map
where
T: IntoIterator<Item = (K, V)>,
K: Into<CBOR>,
V: Into<CBOR>,
{
fn from(container: T) -> Self {
let mut map = Map::new();
for (k, v) in container {
map.insert(k.into(), v.into());
}
map
}
}
impl<K, V> From<HashMap<K, V>> for CBOR
where
K: Into<CBOR>,
V: Into<CBOR>,
{
fn from(container: HashMap<K, V>) -> Self {
CBORCase::Map(Map::from(container.into_iter())).into()
}
}
impl<K, V> TryFrom<CBOR> for HashMap<K, V>
where
K: TryFrom<CBOR, Error = Error> + cmp::Eq + hash::Hash + Clone,
V: TryFrom<CBOR, Error = Error> + Clone,
{
type Error = Error;
fn try_from(cbor: CBOR) -> Result<Self> {
match cbor.into_case() {
CBORCase::Map(map) => {
let mut container = <HashMap<K, V>>::new();
for (k, v) in map.iter() {
container
.insert(k.clone().try_into()?, v.clone().try_into()?);
}
Ok(container)
}
_ => Err(Error::WrongType),
}
}
}
impl TryFrom<CBOR> for HashMap<CBOR, CBOR> {
type Error = Error;
fn try_from(cbor: CBOR) -> Result<Self> {
match cbor.into_case() {
CBORCase::Map(map) => {
let mut container = <HashMap<CBOR, CBOR>>::new();
for (k, v) in map.iter() {
container.insert(k.clone(), v.clone());
}
Ok(container)
}
_ => Err(Error::WrongType),
}
}
}
impl<K, V> From<BTreeMap<K, V>> for CBOR
where
K: Into<CBOR>,
V: Into<CBOR>,
{
fn from(container: BTreeMap<K, V>) -> Self {
CBORCase::Map(Map::from(container.into_iter())).into()
}
}
impl<K, V> TryFrom<CBOR> for BTreeMap<K, V>
where
K: TryFrom<CBOR, Error = Error> + cmp::Eq + cmp::Ord + Clone,
V: TryFrom<CBOR, Error = Error> + Clone,
{
type Error = Error;
fn try_from(cbor: CBOR) -> Result<Self> {
match cbor.into_case() {
CBORCase::Map(map) => {
let mut container = <BTreeMap<K, V>>::new();
for (k, v) in map.iter() {
let key = k.clone().try_into()?;
let value = v.clone().try_into()?;
container.insert(key, value);
}
Ok(container)
}
_ => Err(Error::WrongType),
}
}
}