soroban_sdk/
map.rs

1use core::{
2    cmp::Ordering, convert::Infallible, fmt::Debug, iter::FusedIterator, marker::PhantomData,
3};
4
5use crate::{
6    iter::{UnwrappedEnumerable, UnwrappedIter},
7    unwrap::{UnwrapInfallible, UnwrapOptimized},
8};
9
10use super::{
11    env::internal::{Env as _, MapObject, U32Val},
12    ConversionError, Env, IntoVal, TryFromVal, TryIntoVal, Val, Vec,
13};
14
15#[cfg(not(target_family = "wasm"))]
16use super::xdr::ScVal;
17
18#[cfg(doc)]
19use crate::storage::Storage;
20
21/// Create a [Map] with the given key-value pairs.
22///
23/// The first argument in the list must be a reference to an [Env], then the
24/// key-value pairs follow in a tuple `(key, value)`.
25///
26/// ### Examples
27///
28/// ```
29/// use soroban_sdk::{Env, Map, map};
30///
31/// let env = Env::default();
32/// let map = map![&env, (1, 10), (2, 20)];
33/// assert_eq!(map.len(), 2);
34/// ```
35#[macro_export]
36macro_rules! map {
37    ($env:expr $(,)?) => {
38        $crate::Map::new($env)
39    };
40    ($env:expr, $(($k:expr, $v:expr $(,)?)),+ $(,)?) => {
41        $crate::Map::from_array($env, [$(($k, $v)),+])
42    };
43}
44
45/// Map is a ordered key-value dictionary.
46///
47/// The map is ordered by its keys. Iterating a map is stable and always returns
48/// the keys and values in order of the keys.
49///
50/// The map is stored in the Host and available to the Guest through the
51/// functions defined on Map. Values stored in the Map are transmitted to the
52/// Host as [Val]s, and when retrieved from the Map are transmitted back and
53/// converted from [Val] back into their type.
54///
55/// The pairs of keys and values in a Map are not guaranteed to be of type
56/// `K`/`V` and conversion will fail if they are not. Most functions on Map
57/// return a `Result` due to this.
58///
59/// There are some cases where this lack of guarantee is important:
60///
61/// - When storing a Map that has been provided externally as a contract
62/// function argument, be aware there is no guarantee that all pairs in the Map
63/// will be of type `K` and `V`. It may be necessary to validate all pairs,
64/// either before storing, or when loading with `try_` variation functions.
65///
66/// - When accessing and iterating over a Map that has been provided externally
67/// as a contract function input, and the contract needs to be resilient to
68/// failure, use the `try_` variation functions.
69///
70/// Maps have at most one entry per key. Setting a value for a key in the map
71/// that already has a value for that key replaces the value.
72///
73/// Map values can be stored as [Storage], or in other types like [Vec], [Map],
74/// etc.
75///
76/// ### Examples
77///
78/// Maps can be created and iterated.
79///
80/// ```
81/// use soroban_sdk::{Env, Map, map};
82///
83/// let env = Env::default();
84/// let map = map![&env, (2, 20), (1, 10)];
85/// assert_eq!(map.len(), 2);
86/// assert_eq!(map.iter().next(), Some((1, 10)));
87/// ```
88///
89/// Maps are ordered and so maps created with elements in different order will
90/// be equal.
91///
92/// ```
93/// use soroban_sdk::{Env, Map, map};
94///
95/// let env = Env::default();
96/// assert_eq!(
97///     map![&env, (1, 10), (2, 20)],
98///     map![&env, (2, 20), (1, 10)],
99/// )
100/// ```
101#[derive(Clone)]
102pub struct Map<K, V> {
103    env: Env,
104    obj: MapObject,
105    _k: PhantomData<K>,
106    _v: PhantomData<V>,
107}
108
109impl<K, V> Eq for Map<K, V>
110where
111    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
112    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
113{
114}
115
116impl<K, V> PartialEq for Map<K, V>
117where
118    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
119    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
120{
121    fn eq(&self, other: &Self) -> bool {
122        self.partial_cmp(other) == Some(Ordering::Equal)
123    }
124}
125
126impl<K, V> PartialOrd for Map<K, V>
127where
128    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
129    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
130{
131    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
132        Some(Ord::cmp(self, other))
133    }
134}
135
136impl<K, V> Ord for Map<K, V>
137where
138    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
139    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
140{
141    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
142        #[cfg(not(target_family = "wasm"))]
143        if !self.env.is_same_env(&other.env) {
144            return ScVal::from(self).cmp(&ScVal::from(other));
145        }
146        let v = self
147            .env
148            .obj_cmp(self.obj.to_val(), other.obj.to_val())
149            .unwrap_infallible();
150        v.cmp(&0)
151    }
152}
153
154impl<K, V> Debug for Map<K, V>
155where
156    K: IntoVal<Env, Val> + TryFromVal<Env, Val> + Debug + Clone,
157    K::Error: Debug,
158    V: IntoVal<Env, Val> + TryFromVal<Env, Val> + Debug + Clone,
159    V::Error: Debug,
160{
161    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
162        write!(f, "Map(")?;
163        let mut iter = self.try_iter();
164        if let Some(x) = iter.next() {
165            write!(f, "{:?}", x)?;
166        }
167        for x in iter {
168            write!(f, ", {:?}", x)?;
169        }
170        write!(f, ")")?;
171        Ok(())
172    }
173}
174
175impl<K, V> TryFromVal<Env, MapObject> for Map<K, V>
176where
177    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
178    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
179{
180    type Error = Infallible;
181
182    #[inline(always)]
183    fn try_from_val(env: &Env, obj: &MapObject) -> Result<Self, Self::Error> {
184        Ok(Map {
185            env: env.clone(),
186            obj: *obj,
187            _k: PhantomData,
188            _v: PhantomData,
189        })
190    }
191}
192
193impl<K, V> TryFromVal<Env, Val> for Map<K, V>
194where
195    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
196    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
197{
198    type Error = ConversionError;
199
200    fn try_from_val(env: &Env, val: &Val) -> Result<Self, Self::Error> {
201        Ok(MapObject::try_from_val(env, val)?
202            .try_into_val(env)
203            .unwrap_infallible())
204    }
205}
206
207impl<K, V> TryFromVal<Env, Map<K, V>> for Val
208where
209    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
210    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
211{
212    type Error = Infallible;
213
214    fn try_from_val(_env: &Env, v: &Map<K, V>) -> Result<Self, Self::Error> {
215        Ok(v.to_val())
216    }
217}
218
219impl<K, V> From<Map<K, V>> for Val
220where
221    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
222    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
223{
224    #[inline(always)]
225    fn from(m: Map<K, V>) -> Self {
226        m.obj.into()
227    }
228}
229
230#[cfg(not(target_family = "wasm"))]
231impl<K, V> From<&Map<K, V>> for ScVal {
232    fn from(v: &Map<K, V>) -> Self {
233        // This conversion occurs only in test utilities, and theoretically all
234        // values should convert to an ScVal because the Env won't let the host
235        // type to exist otherwise, unwrapping. Even if there are edge cases
236        // that don't, this is a trade off for a better test developer
237        // experience.
238        ScVal::try_from_val(&v.env, &v.obj.to_val()).unwrap()
239    }
240}
241
242#[cfg(not(target_family = "wasm"))]
243impl<K, V> From<Map<K, V>> for ScVal {
244    fn from(v: Map<K, V>) -> Self {
245        (&v).into()
246    }
247}
248
249#[cfg(not(target_family = "wasm"))]
250impl<K, V> TryFromVal<Env, Map<K, V>> for ScVal {
251    type Error = ConversionError;
252    fn try_from_val(_e: &Env, v: &Map<K, V>) -> Result<Self, ConversionError> {
253        Ok(v.into())
254    }
255}
256
257#[cfg(not(target_family = "wasm"))]
258impl<K, V> TryFromVal<Env, ScVal> for Map<K, V>
259where
260    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
261    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
262{
263    type Error = ConversionError;
264    fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, Self::Error> {
265        Ok(MapObject::try_from_val(env, &Val::try_from_val(env, val)?)?
266            .try_into_val(env)
267            .unwrap_infallible())
268    }
269}
270
271impl<K, V> Map<K, V> {
272    #[inline(always)]
273    pub(crate) unsafe fn unchecked_new(env: Env, obj: MapObject) -> Self {
274        Self {
275            env,
276            obj,
277            _k: PhantomData,
278            _v: PhantomData,
279        }
280    }
281
282    #[inline(always)]
283    pub fn env(&self) -> &Env {
284        &self.env
285    }
286
287    #[inline(always)]
288    pub fn as_val(&self) -> &Val {
289        self.obj.as_val()
290    }
291
292    #[inline(always)]
293    pub fn to_val(&self) -> Val {
294        self.obj.to_val()
295    }
296
297    #[inline(always)]
298    pub(crate) fn as_object(&self) -> &MapObject {
299        &self.obj
300    }
301
302    #[inline(always)]
303    pub(crate) fn to_object(&self) -> MapObject {
304        self.obj
305    }
306}
307
308impl<K, V> Map<K, V>
309where
310    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
311    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
312{
313    /// Create an empty Map.
314    #[inline(always)]
315    pub fn new(env: &Env) -> Map<K, V> {
316        unsafe { Self::unchecked_new(env.clone(), env.map_new().unwrap_infallible()) }
317    }
318
319    /// Create a Map from the key-value pairs in the array.
320    #[inline(always)]
321    pub fn from_array<const N: usize>(env: &Env, items: [(K, V); N]) -> Map<K, V> {
322        let mut map = Map::<K, V>::new(env);
323        for (k, v) in items {
324            map.set(k, v);
325        }
326        map
327    }
328
329    /// Returns true if a key-value pair exists in the map with the given key.
330    #[inline(always)]
331    pub fn contains_key(&self, k: K) -> bool {
332        self.env
333            .map_has(self.obj, k.into_val(&self.env))
334            .unwrap_infallible()
335            .into()
336    }
337
338    /// Returns the value corresponding to the key or None if the map does not
339    /// contain a value with the specified key.
340    ///
341    /// ### Panics
342    ///
343    /// If the value corresponding to the key cannot be converted to type V.
344    #[inline(always)]
345    pub fn get(&self, k: K) -> Option<V> {
346        self.try_get(k).unwrap_optimized()
347    }
348
349    /// Returns the value corresponding to the key or None if the map does not
350    /// contain a value with the specified key.
351    ///
352    /// ### Errors
353    ///
354    /// If the value corresponding to the key cannot be converted to type V.
355    #[inline(always)]
356    pub fn try_get(&self, k: K) -> Result<Option<V>, V::Error> {
357        let env = self.env();
358        let k = k.into_val(env);
359        let has = env.map_has(self.obj, k).unwrap_infallible().into();
360        if has {
361            let v = env.map_get(self.obj, k).unwrap_infallible();
362            V::try_from_val(env, &v).map(|val| Some(val))
363        } else {
364            Ok(None)
365        }
366    }
367
368    /// Returns the value corresponding to the key.
369    ///
370    /// ### Panics
371    ///
372    /// If the map does not contain a value with the specified key.
373    ///
374    /// If the value corresponding to the key cannot be converted to type V.
375    #[inline(always)]
376    pub fn get_unchecked(&self, k: K) -> V {
377        self.try_get_unchecked(k).unwrap_optimized()
378    }
379
380    /// Returns the value corresponding to the key.
381    ///
382    /// ### Errors
383    ///
384    /// If the value corresponding to the key cannot be converted to type V.
385    ///
386    /// ### Panics
387    ///
388    /// If the map does not contain a value with the specified key.
389    #[inline(always)]
390    pub fn try_get_unchecked(&self, k: K) -> Result<V, V::Error> {
391        let env = self.env();
392        let v = env.map_get(self.obj, k.into_val(env)).unwrap_infallible();
393        V::try_from_val(env, &v)
394    }
395
396    /// Set the value for the specified key.
397    ///
398    /// If the map contains a value corresponding to the key, the value is
399    /// replaced with the given value.
400    #[inline(always)]
401    pub fn set(&mut self, k: K, v: V) {
402        let env = self.env();
403        self.obj = env
404            .map_put(self.obj, k.into_val(env), v.into_val(env))
405            .unwrap_infallible();
406    }
407
408    /// Remove the value corresponding to the key.
409    ///
410    /// Returns `None` if the map does not contain a value with the specified
411    /// key.
412    #[inline(always)]
413    pub fn remove(&mut self, k: K) -> Option<()> {
414        let env = self.env();
415        let k = k.into_val(env);
416        let has = env.map_has(self.obj, k).unwrap_infallible().into();
417        if has {
418            self.obj = env.map_del(self.obj, k).unwrap_infallible();
419            Some(())
420        } else {
421            None
422        }
423    }
424
425    /// Remove the value corresponding to the key.
426    ///
427    /// ### Panics
428    ///
429    /// If the map does not contain a value with the specified key.
430    #[inline(always)]
431    pub fn remove_unchecked(&mut self, k: K) {
432        let env = self.env();
433        self.obj = env.map_del(self.obj, k.into_val(env)).unwrap_infallible();
434    }
435
436    /// Returns a [Vec] of all keys in the map.
437    #[inline(always)]
438    pub fn keys(&self) -> Vec<K> {
439        let env = self.env();
440        let vec = env.map_keys(self.obj).unwrap_infallible();
441        Vec::<K>::try_from_val(env, &vec).unwrap()
442    }
443
444    /// Returns a [Vec] of all values in the map.
445    #[inline(always)]
446    pub fn values(&self) -> Vec<V> {
447        let env = self.env();
448        let vec = env.map_values(self.obj).unwrap_infallible();
449        Vec::<V>::try_from_val(env, &vec).unwrap()
450    }
451}
452
453impl<K, V> Map<K, V> {
454    /// Returns true if the map is empty and contains no key-values.
455    #[inline(always)]
456    pub fn is_empty(&self) -> bool {
457        self.len() == 0
458    }
459
460    /// Returns the number of key-value pairs in the map.
461    #[inline(always)]
462    pub fn len(&self) -> u32 {
463        self.env().map_len(self.obj).unwrap_infallible().into()
464    }
465}
466
467impl<K, V> IntoIterator for Map<K, V>
468where
469    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
470    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
471{
472    type Item = (K, V);
473    type IntoIter = UnwrappedIter<MapTryIter<K, V>, (K, V), ConversionError>;
474
475    #[inline(always)]
476    fn into_iter(self) -> Self::IntoIter {
477        MapTryIter::new(self).unwrapped()
478    }
479}
480
481impl<K, V> Map<K, V>
482where
483    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
484    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
485{
486    #[inline(always)]
487    pub fn iter(&self) -> UnwrappedIter<MapTryIter<K, V>, (K, V), ConversionError>
488    where
489        K: Clone,
490        V: Clone,
491    {
492        self.clone().into_iter()
493    }
494
495    #[inline(always)]
496    pub fn try_iter(&self) -> MapTryIter<K, V>
497    where
498        K: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
499        V: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
500    {
501        MapTryIter::new(self.clone())
502    }
503
504    #[inline(always)]
505    pub fn into_try_iter(self) -> MapTryIter<K, V>
506    where
507        K: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
508        V: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
509    {
510        MapTryIter::new(self.clone())
511    }
512}
513
514#[derive(Clone)]
515pub struct MapTryIter<K, V> {
516    map: Map<K, V>,
517    begin: u32,
518    end: u32,
519}
520
521impl<K, V> MapTryIter<K, V> {
522    fn new(map: Map<K, V>) -> Self {
523        Self {
524            begin: 0,
525            end: map.len(),
526            map,
527        }
528    }
529}
530
531impl<K, V> Iterator for MapTryIter<K, V>
532where
533    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
534    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
535{
536    type Item = Result<(K, V), ConversionError>;
537
538    fn next(&mut self) -> Option<Self::Item> {
539        let env = self.map.env();
540        if self.begin >= self.end {
541            return None;
542        }
543        let map_obj = self.map.to_object();
544        let index_val: U32Val = self.begin.into();
545        let key = env.map_key_by_pos(map_obj, index_val).unwrap_infallible();
546        let value = env.map_val_by_pos(map_obj, index_val).unwrap_infallible();
547        self.begin += 1;
548
549        Some(Ok((
550            match K::try_from_val(env, &key) {
551                Ok(k) => k,
552                Err(_) => return Some(Err(ConversionError)),
553            },
554            match V::try_from_val(env, &value) {
555                Ok(v) => v,
556                Err(_) => return Some(Err(ConversionError)),
557            },
558        )))
559    }
560
561    fn size_hint(&self) -> (usize, Option<usize>) {
562        let len = (self.end - self.begin) as usize;
563        (len, Some(len))
564    }
565
566    // TODO: Implement other functions as optimizations.
567}
568
569impl<K, V> DoubleEndedIterator for MapTryIter<K, V>
570where
571    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
572    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
573{
574    fn next_back(&mut self) -> Option<Self::Item> {
575        let env = self.map.env();
576        if self.begin >= self.end {
577            return None;
578        }
579        self.end -= 1;
580        let map_obj = self.map.to_object();
581        let index_val: U32Val = self.end.into();
582        let key = env.map_key_by_pos(map_obj, index_val).unwrap_infallible();
583        let value = env.map_val_by_pos(map_obj, index_val).unwrap_infallible();
584
585        Some(Ok((
586            match K::try_from_val(env, &key) {
587                Ok(k) => k,
588                Err(_) => return Some(Err(ConversionError)),
589            },
590            match V::try_from_val(env, &value) {
591                Ok(v) => v,
592                Err(_) => return Some(Err(ConversionError)),
593            },
594        )))
595    }
596
597    // TODO: Implement other functions as optimizations.
598}
599
600impl<K, V> FusedIterator for MapTryIter<K, V>
601where
602    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
603    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
604{
605}
606
607impl<K, V> ExactSizeIterator for MapTryIter<K, V>
608where
609    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
610    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
611{
612    fn len(&self) -> usize {
613        (self.end - self.begin) as usize
614    }
615}
616
617#[cfg(test)]
618mod test {
619    use super::*;
620    use crate::vec;
621
622    #[test]
623    fn test_map_macro() {
624        let env = Env::default();
625        assert_eq!(map![&env], Map::<i32, i32>::new(&env));
626        assert_eq!(map![&env, (1, 10)], {
627            let mut v = Map::new(&env);
628            v.set(1, 10);
629            v
630        });
631        assert_eq!(map![&env, (1, 10),], {
632            let mut v = Map::new(&env);
633            v.set(1, 10);
634            v
635        });
636        assert_eq!(map![&env, (3, 30), (2, 20), (1, 10),], {
637            let mut v = Map::new(&env);
638            v.set(3, 30);
639            v.set(2, 20);
640            v.set(1, 10);
641            v
642        });
643        assert_eq!(map![&env, (3, 30,), (2, 20,), (1, 10,),], {
644            let mut v = Map::new(&env);
645            v.set(3, 30);
646            v.set(2, 20);
647            v.set(1, 10);
648            v
649        });
650    }
651
652    #[test]
653    fn test_empty() {
654        let env = Env::default();
655
656        let map: Map<(), ()> = map![&env];
657        assert_eq!(map.len(), 0);
658    }
659
660    #[test]
661    fn test_raw_vals() {
662        let env = Env::default();
663
664        let map: Map<u32, bool> = map![&env, (1, true), (2, false)];
665        assert_eq!(map.len(), 2);
666        assert_eq!(map.get(1), Some(true));
667        assert_eq!(map.get(2), Some(false));
668        assert_eq!(map.get(3), None);
669    }
670
671    #[test]
672    fn test_iter() {
673        let env = Env::default();
674
675        let map: Map<(), ()> = map![&env];
676        let mut iter = map.iter();
677        assert_eq!(iter.len(), 0);
678        assert_eq!(iter.next(), None);
679        assert_eq!(iter.next(), None);
680
681        let map = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
682
683        let mut iter = map.iter();
684        assert_eq!(iter.len(), 5);
685        assert_eq!(iter.next(), Some((0, 0)));
686        assert_eq!(iter.len(), 4);
687        assert_eq!(iter.next(), Some((1, 10)));
688        assert_eq!(iter.len(), 3);
689        assert_eq!(iter.next(), Some((2, 20)));
690        assert_eq!(iter.len(), 2);
691        assert_eq!(iter.next(), Some((3, 30)));
692        assert_eq!(iter.len(), 1);
693        assert_eq!(iter.next(), Some((4, 40)));
694        assert_eq!(iter.len(), 0);
695        assert_eq!(iter.next(), None);
696        assert_eq!(iter.next(), None);
697
698        let mut iter = map.iter();
699        assert_eq!(iter.len(), 5);
700        assert_eq!(iter.next(), Some((0, 0)));
701        assert_eq!(iter.len(), 4);
702        assert_eq!(iter.next_back(), Some((4, 40)));
703        assert_eq!(iter.len(), 3);
704        assert_eq!(iter.next_back(), Some((3, 30)));
705        assert_eq!(iter.len(), 2);
706        assert_eq!(iter.next(), Some((1, 10)));
707        assert_eq!(iter.len(), 1);
708        assert_eq!(iter.next(), Some((2, 20)));
709        assert_eq!(iter.len(), 0);
710        assert_eq!(iter.next(), None);
711        assert_eq!(iter.next(), None);
712        assert_eq!(iter.next_back(), None);
713        assert_eq!(iter.next_back(), None);
714
715        let mut iter = map.iter().rev();
716        assert_eq!(iter.len(), 5);
717        assert_eq!(iter.next(), Some((4, 40)));
718        assert_eq!(iter.len(), 4);
719        assert_eq!(iter.next_back(), Some((0, 0)));
720        assert_eq!(iter.len(), 3);
721        assert_eq!(iter.next_back(), Some((1, 10)));
722        assert_eq!(iter.len(), 2);
723        assert_eq!(iter.next(), Some((3, 30)));
724        assert_eq!(iter.len(), 1);
725        assert_eq!(iter.next(), Some((2, 20)));
726        assert_eq!(iter.len(), 0);
727        assert_eq!(iter.next(), None);
728        assert_eq!(iter.next(), None);
729        assert_eq!(iter.next_back(), None);
730        assert_eq!(iter.next_back(), None);
731    }
732
733    #[test]
734    #[should_panic(expected = "ConversionError")]
735    fn test_iter_panic_on_key_conversion() {
736        let env = Env::default();
737
738        let map: Map<Val, Val> = map![&env, (1i64.into_val(&env), 2i32.into_val(&env)),];
739        let map: Val = map.into();
740        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
741
742        let mut iter = map.iter();
743        iter.next();
744    }
745
746    #[test]
747    #[should_panic(expected = "ConversionError")]
748    fn test_iter_panic_on_value_conversion() {
749        let env = Env::default();
750
751        let map: Map<Val, Val> = map![&env, (1i32.into_val(&env), 2i64.into_val(&env)),];
752        let map: Val = map.into();
753        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
754
755        let mut iter = map.iter();
756        iter.next();
757    }
758
759    #[test]
760    fn test_try_iter() {
761        let env = Env::default();
762
763        let map: Map<(), ()> = map![&env];
764        let mut iter = map.iter();
765        assert_eq!(iter.len(), 0);
766        assert_eq!(iter.next(), None);
767        assert_eq!(iter.next(), None);
768
769        let map = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
770
771        let mut iter = map.try_iter();
772        assert_eq!(iter.len(), 5);
773        assert_eq!(iter.next(), Some(Ok((0, 0))));
774        assert_eq!(iter.len(), 4);
775        assert_eq!(iter.next(), Some(Ok((1, 10))));
776        assert_eq!(iter.len(), 3);
777        assert_eq!(iter.next(), Some(Ok((2, 20))));
778        assert_eq!(iter.len(), 2);
779        assert_eq!(iter.next(), Some(Ok((3, 30))));
780        assert_eq!(iter.len(), 1);
781        assert_eq!(iter.next(), Some(Ok((4, 40))));
782        assert_eq!(iter.len(), 0);
783        assert_eq!(iter.next(), None);
784        assert_eq!(iter.next(), None);
785
786        let mut iter = map.try_iter();
787        assert_eq!(iter.len(), 5);
788        assert_eq!(iter.next(), Some(Ok((0, 0))));
789        assert_eq!(iter.len(), 4);
790        assert_eq!(iter.next_back(), Some(Ok((4, 40))));
791        assert_eq!(iter.len(), 3);
792        assert_eq!(iter.next_back(), Some(Ok((3, 30))));
793        assert_eq!(iter.len(), 2);
794        assert_eq!(iter.next(), Some(Ok((1, 10))));
795        assert_eq!(iter.len(), 1);
796        assert_eq!(iter.next(), Some(Ok((2, 20))));
797        assert_eq!(iter.len(), 0);
798        assert_eq!(iter.next(), None);
799        assert_eq!(iter.next(), None);
800        assert_eq!(iter.next_back(), None);
801        assert_eq!(iter.next_back(), None);
802
803        let mut iter = map.try_iter().rev();
804        assert_eq!(iter.len(), 5);
805        assert_eq!(iter.next(), Some(Ok((4, 40))));
806        assert_eq!(iter.len(), 4);
807        assert_eq!(iter.next_back(), Some(Ok((0, 0))));
808        assert_eq!(iter.len(), 3);
809        assert_eq!(iter.next_back(), Some(Ok((1, 10))));
810        assert_eq!(iter.len(), 2);
811        assert_eq!(iter.next(), Some(Ok((3, 30))));
812        assert_eq!(iter.len(), 1);
813        assert_eq!(iter.next(), Some(Ok((2, 20))));
814        assert_eq!(iter.len(), 0);
815        assert_eq!(iter.next(), None);
816        assert_eq!(iter.next(), None);
817        assert_eq!(iter.next_back(), None);
818        assert_eq!(iter.next_back(), None);
819    }
820
821    #[test]
822    fn test_iter_error_on_key_conversion() {
823        let env = Env::default();
824
825        let map: Map<Val, Val> = map![
826            &env,
827            (1i32.into_val(&env), 2i32.into_val(&env)),
828            (3i64.into_val(&env), 4i32.into_val(&env)),
829        ];
830        let map: Val = map.into();
831        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
832
833        let mut iter = map.try_iter();
834        assert_eq!(iter.next(), Some(Ok((1, 2))));
835        assert_eq!(iter.next(), Some(Err(ConversionError)));
836    }
837
838    #[test]
839    fn test_iter_error_on_value_conversion() {
840        let env = Env::default();
841
842        let map: Map<Val, Val> = map![
843            &env,
844            (1i32.into_val(&env), 2i32.into_val(&env)),
845            (3i32.into_val(&env), 4i64.into_val(&env)),
846        ];
847        let map: Val = map.into();
848        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
849
850        let mut iter = map.try_iter();
851        assert_eq!(iter.next(), Some(Ok((1, 2))));
852        assert_eq!(iter.next(), Some(Err(ConversionError)));
853    }
854
855    #[test]
856    fn test_keys() {
857        let env = Env::default();
858
859        let map = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
860        let keys = map.keys();
861        assert_eq!(keys, vec![&env, 0, 1, 2, 3, 4]);
862    }
863
864    #[test]
865    fn test_values() {
866        let env = Env::default();
867
868        let map = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
869        let values = map.values();
870        assert_eq!(values, vec![&env, 0, 10, 20, 30, 40]);
871    }
872
873    #[test]
874    fn test_from_array() {
875        let env = Env::default();
876
877        let map = Map::from_array(&env, [(0, 0), (1, 10), (2, 20), (3, 30), (4, 40)]);
878        assert_eq!(map, map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)]);
879
880        let map: Map<u32, u32> = Map::from_array(&env, []);
881        assert_eq!(map, map![&env]);
882    }
883
884    #[test]
885    fn test_contains_key() {
886        let env = Env::default();
887
888        let map: Map<u32, u32> = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
889
890        // contains all assigned keys
891        for i in 0..map.len() {
892            assert_eq!(true, map.contains_key(i));
893        }
894
895        // does not contain keys outside range
896        assert_eq!(map.contains_key(6), false);
897        assert_eq!(map.contains_key(u32::MAX), false);
898        assert_eq!(map.contains_key(8), false);
899    }
900
901    #[test]
902    fn test_is_empty() {
903        let env = Env::default();
904
905        let mut map: Map<u32, u32> = Map::new(&env);
906        assert_eq!(map.is_empty(), true);
907        map.set(0, 0);
908        assert_eq!(map.is_empty(), false);
909    }
910
911    #[test]
912    fn test_get() {
913        let env = Env::default();
914
915        let map: Map<u32, u32> = map![&env, (0, 0), (1, 10)];
916        assert_eq!(map.get(0), Some(0));
917        assert_eq!(map.get(1), Some(10));
918        assert_eq!(map.get(2), None);
919    }
920
921    #[test]
922    fn test_get_none_on_key_type_mismatch() {
923        let env = Env::default();
924
925        let map: Map<Val, Val> = map![
926            &env,
927            (1i32.into_val(&env), 2i32.into_val(&env)),
928            (3i64.into_val(&env), 4i32.into_val(&env)),
929        ];
930        let map: Val = map.into();
931        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
932        assert_eq!(map.get(1), Some(2));
933        assert_eq!(map.get(3), None);
934    }
935
936    #[test]
937    #[should_panic(expected = "ConversionError")]
938    fn test_get_panics_on_value_conversion() {
939        let env = Env::default();
940
941        let map: Map<Val, Val> = map![&env, (1i32.into_val(&env), 2i64.into_val(&env)),];
942        let map: Val = map.into();
943        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
944        let _ = map.get(1);
945    }
946
947    #[test]
948    fn test_try_get() {
949        let env = Env::default();
950
951        let map: Map<u32, u32> = map![&env, (0, 0), (1, 10)];
952        assert_eq!(map.try_get(0), Ok(Some(0)));
953        assert_eq!(map.try_get(1), Ok(Some(10)));
954        assert_eq!(map.try_get(2), Ok(None));
955    }
956
957    #[test]
958    fn test_try_get_none_on_key_type_mismatch() {
959        let env = Env::default();
960
961        let map: Map<Val, Val> = map![
962            &env,
963            (1i32.into_val(&env), 2i32.into_val(&env)),
964            (3i64.into_val(&env), 4i32.into_val(&env)),
965        ];
966        let map: Val = map.into();
967        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
968        assert_eq!(map.try_get(1), Ok(Some(2)));
969        assert_eq!(map.try_get(3), Ok(None));
970    }
971
972    #[test]
973    fn test_try_get_errors_on_value_conversion() {
974        let env = Env::default();
975
976        let map: Map<Val, Val> = map![
977            &env,
978            (1i32.into_val(&env), 2i32.into_val(&env)),
979            (3i32.into_val(&env), 4i64.into_val(&env)),
980        ];
981        let map: Val = map.into();
982        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
983        assert_eq!(map.try_get(1), Ok(Some(2)));
984        assert_eq!(map.try_get(3), Err(ConversionError));
985    }
986
987    #[test]
988    fn test_get_unchecked() {
989        let env = Env::default();
990
991        let map: Map<u32, u32> = map![&env, (0, 0), (1, 10)];
992        assert_eq!(map.get_unchecked(0), 0);
993        assert_eq!(map.get_unchecked(1), 10);
994    }
995
996    #[test]
997    #[should_panic(expected = "HostError: Error(Object, MissingValue)")]
998    fn test_get_unchecked_panics_on_key_type_mismatch() {
999        let env = Env::default();
1000
1001        let map: Map<Val, Val> = map![&env, (1i64.into_val(&env), 2i32.into_val(&env)),];
1002        let map: Val = map.into();
1003        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
1004        let _ = map.get_unchecked(1);
1005    }
1006
1007    #[test]
1008    #[should_panic(expected = "ConversionError")]
1009    fn test_get_unchecked_panics_on_value_conversion() {
1010        let env = Env::default();
1011
1012        let map: Map<Val, Val> = map![&env, (1i32.into_val(&env), 2i64.into_val(&env)),];
1013        let map: Val = map.into();
1014        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
1015        let _ = map.get_unchecked(1);
1016    }
1017
1018    #[test]
1019    fn test_try_get_unchecked() {
1020        let env = Env::default();
1021
1022        let map: Map<u32, u32> = map![&env, (0, 0), (1, 10)];
1023        assert_eq!(map.get_unchecked(0), 0);
1024        assert_eq!(map.get_unchecked(1), 10);
1025    }
1026
1027    #[test]
1028    #[should_panic(expected = "HostError: Error(Object, MissingValue)")]
1029    fn test_try_get_unchecked_panics_on_key_type_mismatch() {
1030        let env = Env::default();
1031
1032        let map: Map<Val, Val> = map![&env, (1i64.into_val(&env), 2i32.into_val(&env)),];
1033        let map: Val = map.into();
1034        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
1035        let _ = map.try_get_unchecked(1);
1036    }
1037
1038    #[test]
1039    fn test_try_get_unchecked_errors_on_value_conversion() {
1040        let env = Env::default();
1041
1042        let map: Map<Val, Val> = map![
1043            &env,
1044            (1i32.into_val(&env), 2i32.into_val(&env)),
1045            (3i32.into_val(&env), 4i64.into_val(&env)),
1046        ];
1047        let map: Val = map.into();
1048        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
1049        assert_eq!(map.try_get_unchecked(1), Ok(2));
1050        assert_eq!(map.try_get_unchecked(3), Err(ConversionError));
1051    }
1052
1053    #[test]
1054    fn test_remove() {
1055        let env = Env::default();
1056
1057        let mut map: Map<u32, u32> = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
1058
1059        assert_eq!(map.len(), 5);
1060        assert_eq!(map.get(2), Some(20));
1061        assert_eq!(map.remove(2), Some(()));
1062        assert_eq!(map.get(2), None);
1063        assert_eq!(map.len(), 4);
1064
1065        // remove all items
1066        map.remove(0);
1067        map.remove(1);
1068        map.remove(3);
1069        map.remove(4);
1070        assert_eq!(map![&env], map);
1071
1072        // removing from empty map
1073        let mut map: Map<u32, u32> = map![&env];
1074        assert_eq!(map.remove(0), None);
1075        assert_eq!(map.remove(u32::MAX), None);
1076    }
1077
1078    #[test]
1079    fn test_remove_unchecked() {
1080        let env = Env::default();
1081
1082        let mut map: Map<u32, u32> = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
1083
1084        assert_eq!(map.len(), 5);
1085        assert_eq!(map.get(2), Some(20));
1086        map.remove_unchecked(2);
1087        assert_eq!(map.get(2), None);
1088        assert_eq!(map.len(), 4);
1089
1090        // remove all items
1091        map.remove_unchecked(0);
1092        map.remove_unchecked(1);
1093        map.remove_unchecked(3);
1094        map.remove_unchecked(4);
1095        assert_eq!(map![&env], map);
1096    }
1097
1098    #[test]
1099    #[should_panic(expected = "HostError: Error(Object, MissingValue)")]
1100    fn test_remove_unchecked_panic() {
1101        let env = Env::default();
1102        let mut map: Map<u32, u32> = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
1103        map.remove_unchecked(100); // key does not exist
1104    }
1105}