Skip to main content

neo_types/
map.rs

1// Copyright (c) 2025-2026 R3E Network
2// Licensed under the MIT License
3
4use std::vec::Vec;
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9/// Neo N3 Map type
10#[derive(Debug, Clone, PartialEq, Eq)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12#[cfg_attr(
13    feature = "serde",
14    serde(bound(
15        serialize = "K: Serialize + Eq, V: Serialize",
16        deserialize = "K: Deserialize<'de> + Eq, V: Deserialize<'de>"
17    ))
18)]
19pub struct NeoMap<K, V> {
20    data: Vec<(K, V)>,
21}
22
23impl<K, V> NeoMap<K, V> {
24    pub fn new() -> Self {
25        Self { data: Vec::new() }
26    }
27
28    pub fn insert(&mut self, key: K, value: V) -> Option<V>
29    where
30        K: PartialEq,
31    {
32        for (k, v) in &mut self.data {
33            if *k == key {
34                return Some(core::mem::replace(v, value));
35            }
36        }
37        self.data.push((key, value));
38        None
39    }
40
41    /// Gets a reference to the value associated with the given key.
42    ///
43    /// # Performance
44    /// This operation is O(n) as it performs a linear search.
45    /// Consider using a HashMap for O(1) lookups if performance is critical.
46    pub fn get(&self, key: &K) -> Option<&V>
47    where
48        K: PartialEq,
49    {
50        self.data.iter().find(|(k, _)| k == key).map(|(_, v)| v)
51    }
52
53    /// Gets a mutable reference to the value associated with the given key.
54    ///
55    /// # Performance
56    /// This operation is O(n) as it performs a linear search.
57    pub fn get_mut(&mut self, key: &K) -> Option<&mut V>
58    where
59        K: PartialEq,
60    {
61        self.data.iter_mut().find(|(k, _)| k == key).map(|(_, v)| v)
62    }
63
64    /// Removes the key-value pair associated with the given key.
65    ///
66    /// # Performance
67    /// This operation is O(n) due to the element removal.
68    pub fn remove(&mut self, key: &K) -> Option<V>
69    where
70        K: PartialEq,
71    {
72        self.data
73            .iter()
74            .position(|(k, _)| k == key)
75            .map(|i| self.data.swap_remove(i).1)
76    }
77
78    pub fn len(&self) -> usize {
79        self.data.len()
80    }
81
82    pub fn is_empty(&self) -> bool {
83        self.data.is_empty()
84    }
85
86    pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
87        self.data.iter().map(|(k, v)| (k, v))
88    }
89
90    /// Returns true if the map contains the given key.
91    pub fn contains_key(&self, key: &K) -> bool
92    where
93        K: PartialEq,
94    {
95        self.data.iter().any(|(k, _)| k == key)
96    }
97
98    /// Returns an iterator over the keys of the map.
99    pub fn keys(&self) -> impl Iterator<Item = &K> {
100        self.data.iter().map(|(k, _)| k)
101    }
102
103    /// Returns an iterator over the values of the map.
104    pub fn values(&self) -> impl Iterator<Item = &V> {
105        self.data.iter().map(|(_, v)| v)
106    }
107}
108
109impl<K, V> Default for NeoMap<K, V> {
110    fn default() -> Self {
111        Self::new()
112    }
113}
114
115impl<K, V> IntoIterator for NeoMap<K, V> {
116    type Item = (K, V);
117    type IntoIter = std::vec::IntoIter<(K, V)>;
118    fn into_iter(self) -> Self::IntoIter {
119        self.data.into_iter()
120    }
121}
122
123impl<'a, K, V> IntoIterator for &'a NeoMap<K, V> {
124    type Item = &'a (K, V);
125    type IntoIter = std::slice::Iter<'a, (K, V)>;
126    fn into_iter(self) -> Self::IntoIter {
127        self.data.iter()
128    }
129}