use anchor_lang::prelude::*;
use std::collections::HashMap;
#[cfg(feature = "compression")]
use crate::compression::*;
#[cfg(feature = "schema")]
use crate::schema::*;
#[cfg_attr(feature = "debug", derive(Debug))]
#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq)]
pub struct KeyValue<
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> {
key: K,
value: V,
}
impl<
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> Into<(K, V)> for KeyValue<K, V>
{
fn into(self) -> (K, V) {
(self.key, self.value)
}
}
impl<
'i,
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> Into<(&'i K, &'i V)> for &'i KeyValue<K, V>
{
fn into(self) -> (&'i K, &'i V) {
(&self.key, &self.value)
}
}
impl<
'i,
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> Into<(&'i K, &'i mut V)> for &'i mut KeyValue<K, V>
{
fn into(self) -> (&'i K, &'i mut V) {
(&self.key, &mut self.value)
}
}
impl<
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> From<(&K, &V)> for KeyValue<K, V>
{
fn from((key, value): (&K, &V)) -> Self {
KeyValue {
key: key.to_owned(),
value: value.to_owned(),
}
}
}
impl<
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> From<(K, V)> for KeyValue<K, V>
{
fn from((key, value): (K, V)) -> Self {
Self { key, value }
}
}
#[cfg_attr(feature = "debug", derive(Debug))]
#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq)]
pub struct VecMap<
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> {
_inner: Vec<KeyValue<K, V>>,
}
impl<
K: AnchorSerialize + AnchorDeserialize + Clone + PartialEq,
V: AnchorSerialize + AnchorDeserialize + Clone,
> VecMap<K, V>
{
pub fn new() -> Self {
Self { _inner: vec![] }
}
pub fn into_inner(self) -> Vec<KeyValue<K, V>> {
self._inner
}
pub fn insert(&mut self, key: K, value: V) {
for KeyValue { key: k, value: v } in &mut self._inner {
if k == &key {
*v = value;
return;
}
}
self._inner.push(KeyValue { key, value });
}
pub fn get(&self, key: &K) -> Option<&V> {
self._inner
.iter()
.find_map(|KeyValue { key: k, value: v }| if k == key { Some(v) } else { None })
}
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
self._inner
.iter_mut()
.find_map(|KeyValue { key: k, value: v }| if k == key { Some(v) } else { None })
}
pub fn iter<'i>(&'i self) -> impl Iterator<Item = (&'i K, &'i V)> {
let a = self._inner.iter().map(|i| -> (&K, &V) { i.into() });
a
}
pub fn iter_mut<'i>(&'i mut self) -> impl Iterator<Item = (&'i K, &'i mut V)> {
let a = self._inner.iter_mut().map(|i| -> (&K, &mut V) { i.into() });
a
}
pub fn remove(&mut self, key: &K) {
self._inner.retain(|KeyValue { key: k, .. }| k != key);
}
}
pub struct VecMapIter<
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> {
inner: std::vec::IntoIter<KeyValue<K, V>>,
}
impl<
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> Iterator for VecMapIter<K, V>
where
K: Clone,
V: Clone,
{
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|kv| (kv.key, kv.value))
}
}
impl<
K: AnchorSerialize + AnchorDeserialize + Clone + PartialEq,
V: AnchorSerialize + AnchorDeserialize + Clone,
> FromIterator<(K, V)> for VecMap<K, V>
{
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
let mut vec_map = VecMap::new();
for (key, value) in iter {
vec_map._inner.push(KeyValue { key, value });
}
vec_map
}
}
impl<
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> IntoIterator for VecMap<K, V>
where
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
{
type Item = (K, V);
type IntoIter = VecMapIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
VecMapIter {
inner: self._inner.into_iter(),
}
}
}
impl<
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> FromIterator<KeyValue<K, V>> for VecMap<K, V>
{
fn from_iter<T: IntoIterator<Item = KeyValue<K, V>>>(iter: T) -> Self {
Self {
_inner: iter.into_iter().collect(),
}
}
}
impl<
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> From<&HashMap<K, V>> for VecMap<K, V>
{
fn from(map: &HashMap<K, V>) -> Self {
Self {
_inner: map
.iter()
.map(|(k, v)| KeyValue {
key: k.clone(),
value: v.clone(),
})
.collect(),
}
}
}
impl<
K: AnchorSerialize + AnchorDeserialize + Clone,
V: AnchorSerialize + AnchorDeserialize + Clone,
> From<HashMap<K, V>> for VecMap<K, V>
{
fn from(map: HashMap<K, V>) -> Self {
Self {
_inner: map
.into_iter()
.map(|(k, v)| KeyValue { key: k, value: v })
.collect(),
}
}
}
#[cfg(feature = "compression")]
impl<
K: AnchorSerialize + AnchorDeserialize + Clone + ToNode,
V: AnchorSerialize + AnchorDeserialize + Clone + ToNode,
> ToNode for VecMap<K, V>
{
fn to_node(&self) -> [u8; 32] {
let mut seeds: Vec<[u8; 32]> = vec![];
for KeyValue { key, value } in &self._inner {
seeds.push(key.to_node());
seeds.push(value.to_node());
}
let seeds_refs: Vec<&[u8]> = seeds.iter().map(|node| &node[..]).collect();
anchor_lang::solana_program::keccak::hashv(&seeds_refs[..]).to_bytes()
}
}
#[cfg(feature = "schema")]
impl<
K: AnchorSerialize + AnchorDeserialize + Clone + ToSchema + PartialEq,
V: AnchorSerialize + AnchorDeserialize + Clone + ToSchema,
> ToSchema for VecMap<K, V>
{
fn schema() -> Schema {
Schema::VecMap(Box::new(K::schema()), Box::new(V::schema()))
}
fn schema_value(&self) -> SchemaValue {
let mut schema = VecMap::<SchemaValue, SchemaValue>::new();
self._inner.iter().for_each(|KeyValue { key, value }| {
schema.insert(key.schema_value(), value.schema_value());
});
SchemaValue::VecMap(schema)
}
}