| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| // Copyright by contributors to this project. |
| // SPDX-License-Identifier: (Apache-2.0 OR MIT) |
| |
| use alloc::vec::Vec; |
| use core::{ |
| hash::Hash, |
| ops::{Deref, DerefMut}, |
| }; |
| |
| use map_impl::SmallMapInner; |
| pub use map_impl::{LargeMap, LargeMapEntry, SmallMap}; |
| use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize}; |
| |
| #[cfg(feature = "std")] |
| mod map_impl { |
| use core::hash::Hash; |
| use std::collections::{hash_map::Entry, HashMap}; |
| |
| #[derive(Clone, Debug, PartialEq, Eq)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct SmallMap<K: Hash + Eq, V>(pub(super) HashMap<K, V>); |
| |
| pub type LargeMap<K, V> = SmallMap<K, V>; |
| pub(super) type SmallMapInner<K, V> = HashMap<K, V>; |
| pub type LargeMapEntry<'a, K, V> = Entry<'a, K, V>; |
| } |
| |
| #[cfg(not(feature = "std"))] |
| mod map_impl { |
| use core::hash::Hash; |
| |
| use alloc::{ |
| collections::{btree_map::Entry, BTreeMap}, |
| vec::Vec, |
| }; |
| #[cfg(feature = "by_ref_proposal")] |
| use itertools::Itertools; |
| |
| #[derive(Clone, Debug, PartialEq, Eq)] |
| pub struct SmallMap<K: Hash + Eq, V>(pub(super) Vec<(K, V)>); |
| |
| pub type LargeMap<K, V> = BTreeMap<K, V>; |
| pub(super) type SmallMapInner<K, V> = Vec<(K, V)>; |
| pub type LargeMapEntry<'a, K, V> = Entry<'a, K, V>; |
| |
| #[cfg(feature = "by_ref_proposal")] |
| impl<K: Hash + Eq, V> SmallMap<K, V> { |
| pub fn get(&self, key: &K) -> Option<&V> { |
| self.find(key).map(|i| &self.0[i].1) |
| } |
| |
| pub fn insert(&mut self, key: K, value: V) { |
| match self.0.iter_mut().find(|(k, _)| (k == &key)) { |
| Some((_, v)) => *v = value, |
| None => self.0.push((key, value)), |
| } |
| } |
| |
| pub fn remove(&mut self, key: &K) -> Option<V> { |
| self.find(key).map(|i| self.0.remove(i).1) |
| } |
| |
| fn find(&self, key: &K) -> Option<usize> { |
| self.0.iter().position(|(k, _)| k == key) |
| } |
| } |
| } |
| |
| impl<K: Hash + Eq, V> Default for SmallMap<K, V> { |
| fn default() -> Self { |
| Self(SmallMapInner::new()) |
| } |
| } |
| |
| impl<K: Hash + Eq, V> Deref for SmallMap<K, V> { |
| type Target = SmallMapInner<K, V>; |
| |
| fn deref(&self) -> &Self::Target { |
| &self.0 |
| } |
| } |
| |
| impl<K: Hash + Eq, V> DerefMut for SmallMap<K, V> { |
| fn deref_mut(&mut self) -> &mut Self::Target { |
| &mut self.0 |
| } |
| } |
| |
| impl<K, V> MlsDecode for SmallMap<K, V> |
| where |
| K: Hash + Eq + MlsEncode + MlsDecode + MlsSize, |
| V: MlsEncode + MlsDecode + MlsSize, |
| { |
| fn mls_decode(reader: &mut &[u8]) -> Result<Self, mls_rs_codec::Error> { |
| SmallMapInner::mls_decode(reader).map(Self) |
| } |
| } |
| |
| impl<K, V> MlsSize for SmallMap<K, V> |
| where |
| K: Hash + Eq + MlsEncode + MlsDecode + MlsSize, |
| V: MlsEncode + MlsDecode + MlsSize, |
| { |
| fn mls_encoded_len(&self) -> usize { |
| self.0.mls_encoded_len() |
| } |
| } |
| |
| impl<K, V> MlsEncode for SmallMap<K, V> |
| where |
| K: Hash + Eq + MlsEncode + MlsDecode + MlsSize, |
| V: MlsEncode + MlsDecode + MlsSize, |
| { |
| fn mls_encode(&self, writer: &mut Vec<u8>) -> Result<(), mls_rs_codec::Error> { |
| self.0.mls_encode(writer) |
| } |
| } |