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> TryFromVal<Env, &Map<K, V>> for Val
220where
221    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
222    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
223{
224    type Error = Infallible;
225
226    fn try_from_val(_env: &Env, v: &&Map<K, V>) -> Result<Self, Self::Error> {
227        Ok(v.to_val())
228    }
229}
230
231impl<K, V> From<Map<K, V>> for Val
232where
233    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
234    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
235{
236    #[inline(always)]
237    fn from(m: Map<K, V>) -> Self {
238        m.obj.into()
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        // This conversion occurs only in test utilities, and theoretically all
246        // values should convert to an ScVal because the Env won't let the host
247        // type to exist otherwise, unwrapping. Even if there are edge cases
248        // that don't, this is a trade off for a better test developer
249        // experience.
250        ScVal::try_from_val(&v.env, &v.obj.to_val()).unwrap()
251    }
252}
253
254#[cfg(not(target_family = "wasm"))]
255impl<K, V> From<Map<K, V>> for ScVal {
256    fn from(v: Map<K, V>) -> Self {
257        (&v).into()
258    }
259}
260
261#[cfg(not(target_family = "wasm"))]
262impl<K, V> TryFromVal<Env, Map<K, V>> for ScVal {
263    type Error = ConversionError;
264    fn try_from_val(_e: &Env, v: &Map<K, V>) -> Result<Self, ConversionError> {
265        Ok(v.into())
266    }
267}
268
269#[cfg(not(target_family = "wasm"))]
270impl<K, V> TryFromVal<Env, ScVal> for Map<K, V>
271where
272    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
273    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
274{
275    type Error = ConversionError;
276    fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, Self::Error> {
277        Ok(MapObject::try_from_val(env, &Val::try_from_val(env, val)?)?
278            .try_into_val(env)
279            .unwrap_infallible())
280    }
281}
282
283impl<K, V> Map<K, V> {
284    #[inline(always)]
285    pub(crate) unsafe fn unchecked_new(env: Env, obj: MapObject) -> Self {
286        Self {
287            env,
288            obj,
289            _k: PhantomData,
290            _v: PhantomData,
291        }
292    }
293
294    #[inline(always)]
295    pub fn env(&self) -> &Env {
296        &self.env
297    }
298
299    #[inline(always)]
300    pub fn as_val(&self) -> &Val {
301        self.obj.as_val()
302    }
303
304    #[inline(always)]
305    pub fn to_val(&self) -> Val {
306        self.obj.to_val()
307    }
308
309    #[inline(always)]
310    pub(crate) fn as_object(&self) -> &MapObject {
311        &self.obj
312    }
313
314    #[inline(always)]
315    pub(crate) fn to_object(&self) -> MapObject {
316        self.obj
317    }
318}
319
320impl<K, V> Map<K, V>
321where
322    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
323    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
324{
325    /// Create an empty Map.
326    #[inline(always)]
327    pub fn new(env: &Env) -> Map<K, V> {
328        unsafe { Self::unchecked_new(env.clone(), env.map_new().unwrap_infallible()) }
329    }
330
331    /// Create a Map from the key-value pairs in the array.
332    #[inline(always)]
333    pub fn from_array<const N: usize>(env: &Env, items: [(K, V); N]) -> Map<K, V> {
334        let mut map = Map::<K, V>::new(env);
335        for (k, v) in items {
336            map.set(k, v);
337        }
338        map
339    }
340
341    /// Returns true if a key-value pair exists in the map with the given key.
342    #[inline(always)]
343    pub fn contains_key(&self, k: K) -> bool {
344        self.env
345            .map_has(self.obj, k.into_val(&self.env))
346            .unwrap_infallible()
347            .into()
348    }
349
350    /// Returns the value corresponding to the key or None if the map does not
351    /// contain a value with the specified key.
352    ///
353    /// ### Panics
354    ///
355    /// If the value corresponding to the key cannot be converted to type V.
356    #[inline(always)]
357    pub fn get(&self, k: K) -> Option<V> {
358        self.try_get(k).unwrap_optimized()
359    }
360
361    /// Returns the value corresponding to the key or None if the map does not
362    /// contain a value with the specified key.
363    ///
364    /// ### Errors
365    ///
366    /// If the value corresponding to the key cannot be converted to type V.
367    #[inline(always)]
368    pub fn try_get(&self, k: K) -> Result<Option<V>, V::Error> {
369        let env = self.env();
370        let k = k.into_val(env);
371        let has = env.map_has(self.obj, k).unwrap_infallible().into();
372        if has {
373            let v = env.map_get(self.obj, k).unwrap_infallible();
374            V::try_from_val(env, &v).map(|val| Some(val))
375        } else {
376            Ok(None)
377        }
378    }
379
380    /// Returns the value corresponding to the key.
381    ///
382    /// ### Panics
383    ///
384    /// If the map does not contain a value with the specified key.
385    ///
386    /// If the value corresponding to the key cannot be converted to type V.
387    #[inline(always)]
388    pub fn get_unchecked(&self, k: K) -> V {
389        self.try_get_unchecked(k).unwrap_optimized()
390    }
391
392    /// Returns the value corresponding to the key.
393    ///
394    /// ### Errors
395    ///
396    /// If the value corresponding to the key cannot be converted to type V.
397    ///
398    /// ### Panics
399    ///
400    /// If the map does not contain a value with the specified key.
401    #[inline(always)]
402    pub fn try_get_unchecked(&self, k: K) -> Result<V, V::Error> {
403        let env = self.env();
404        let v = env.map_get(self.obj, k.into_val(env)).unwrap_infallible();
405        V::try_from_val(env, &v)
406    }
407
408    /// Set the value for the specified key.
409    ///
410    /// If the map contains a value corresponding to the key, the value is
411    /// replaced with the given value.
412    #[inline(always)]
413    pub fn set(&mut self, k: K, v: V) {
414        let env = self.env();
415        self.obj = env
416            .map_put(self.obj, k.into_val(env), v.into_val(env))
417            .unwrap_infallible();
418    }
419
420    /// Remove the value corresponding to the key.
421    ///
422    /// Returns `None` if the map does not contain a value with the specified
423    /// key.
424    #[inline(always)]
425    pub fn remove(&mut self, k: K) -> Option<()> {
426        let env = self.env();
427        let k = k.into_val(env);
428        let has = env.map_has(self.obj, k).unwrap_infallible().into();
429        if has {
430            self.obj = env.map_del(self.obj, k).unwrap_infallible();
431            Some(())
432        } else {
433            None
434        }
435    }
436
437    /// Remove the value corresponding to the key.
438    ///
439    /// ### Panics
440    ///
441    /// If the map does not contain a value with the specified key.
442    #[inline(always)]
443    pub fn remove_unchecked(&mut self, k: K) {
444        let env = self.env();
445        self.obj = env.map_del(self.obj, k.into_val(env)).unwrap_infallible();
446    }
447
448    /// Returns a [Vec] of all keys in the map.
449    #[inline(always)]
450    pub fn keys(&self) -> Vec<K> {
451        let env = self.env();
452        let vec = env.map_keys(self.obj).unwrap_infallible();
453        Vec::<K>::try_from_val(env, &vec).unwrap()
454    }
455
456    /// Returns a [Vec] of all values in the map.
457    #[inline(always)]
458    pub fn values(&self) -> Vec<V> {
459        let env = self.env();
460        let vec = env.map_values(self.obj).unwrap_infallible();
461        Vec::<V>::try_from_val(env, &vec).unwrap()
462    }
463}
464
465impl<K, V> Map<K, V> {
466    /// Returns true if the map is empty and contains no key-values.
467    #[inline(always)]
468    pub fn is_empty(&self) -> bool {
469        self.len() == 0
470    }
471
472    /// Returns the number of key-value pairs in the map.
473    #[inline(always)]
474    pub fn len(&self) -> u32 {
475        self.env().map_len(self.obj).unwrap_infallible().into()
476    }
477}
478
479impl<K, V> IntoIterator for Map<K, V>
480where
481    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
482    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
483{
484    type Item = (K, V);
485    type IntoIter = UnwrappedIter<MapTryIter<K, V>, (K, V), ConversionError>;
486
487    #[inline(always)]
488    fn into_iter(self) -> Self::IntoIter {
489        MapTryIter::new(self).unwrapped()
490    }
491}
492
493impl<K, V> Map<K, V>
494where
495    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
496    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
497{
498    #[inline(always)]
499    pub fn iter(&self) -> UnwrappedIter<MapTryIter<K, V>, (K, V), ConversionError>
500    where
501        K: Clone,
502        V: Clone,
503    {
504        self.clone().into_iter()
505    }
506
507    #[inline(always)]
508    pub fn try_iter(&self) -> MapTryIter<K, V>
509    where
510        K: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
511        V: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
512    {
513        MapTryIter::new(self.clone())
514    }
515
516    #[inline(always)]
517    pub fn into_try_iter(self) -> MapTryIter<K, V>
518    where
519        K: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
520        V: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
521    {
522        MapTryIter::new(self.clone())
523    }
524}
525
526#[derive(Clone)]
527pub struct MapTryIter<K, V> {
528    map: Map<K, V>,
529    begin: u32,
530    end: u32,
531}
532
533impl<K, V> MapTryIter<K, V> {
534    fn new(map: Map<K, V>) -> Self {
535        Self {
536            begin: 0,
537            end: map.len(),
538            map,
539        }
540    }
541}
542
543impl<K, V> Iterator for MapTryIter<K, V>
544where
545    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
546    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
547{
548    type Item = Result<(K, V), ConversionError>;
549
550    fn next(&mut self) -> Option<Self::Item> {
551        let env = self.map.env();
552        if self.begin >= self.end {
553            return None;
554        }
555        let map_obj = self.map.to_object();
556        let index_val: U32Val = self.begin.into();
557        let key = env.map_key_by_pos(map_obj, index_val).unwrap_infallible();
558        let value = env.map_val_by_pos(map_obj, index_val).unwrap_infallible();
559        self.begin += 1;
560
561        Some(Ok((
562            match K::try_from_val(env, &key) {
563                Ok(k) => k,
564                Err(_) => return Some(Err(ConversionError)),
565            },
566            match V::try_from_val(env, &value) {
567                Ok(v) => v,
568                Err(_) => return Some(Err(ConversionError)),
569            },
570        )))
571    }
572
573    fn size_hint(&self) -> (usize, Option<usize>) {
574        let len = (self.end - self.begin) as usize;
575        (len, Some(len))
576    }
577
578    // TODO: Implement other functions as optimizations.
579}
580
581impl<K, V> DoubleEndedIterator for MapTryIter<K, V>
582where
583    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
584    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
585{
586    fn next_back(&mut self) -> Option<Self::Item> {
587        let env = self.map.env();
588        if self.begin >= self.end {
589            return None;
590        }
591        self.end -= 1;
592        let map_obj = self.map.to_object();
593        let index_val: U32Val = self.end.into();
594        let key = env.map_key_by_pos(map_obj, index_val).unwrap_infallible();
595        let value = env.map_val_by_pos(map_obj, index_val).unwrap_infallible();
596
597        Some(Ok((
598            match K::try_from_val(env, &key) {
599                Ok(k) => k,
600                Err(_) => return Some(Err(ConversionError)),
601            },
602            match V::try_from_val(env, &value) {
603                Ok(v) => v,
604                Err(_) => return Some(Err(ConversionError)),
605            },
606        )))
607    }
608
609    // TODO: Implement other functions as optimizations.
610}
611
612impl<K, V> FusedIterator for MapTryIter<K, V>
613where
614    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
615    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
616{
617}
618
619impl<K, V> ExactSizeIterator for MapTryIter<K, V>
620where
621    K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
622    V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
623{
624    fn len(&self) -> usize {
625        (self.end - self.begin) as usize
626    }
627}
628
629#[cfg(test)]
630mod test {
631    use super::*;
632    use crate::vec;
633
634    #[test]
635    fn test_map_macro() {
636        let env = Env::default();
637        assert_eq!(map![&env], Map::<i32, i32>::new(&env));
638        assert_eq!(map![&env, (1, 10)], {
639            let mut v = Map::new(&env);
640            v.set(1, 10);
641            v
642        });
643        assert_eq!(map![&env, (1, 10),], {
644            let mut v = Map::new(&env);
645            v.set(1, 10);
646            v
647        });
648        assert_eq!(map![&env, (3, 30), (2, 20), (1, 10),], {
649            let mut v = Map::new(&env);
650            v.set(3, 30);
651            v.set(2, 20);
652            v.set(1, 10);
653            v
654        });
655        assert_eq!(map![&env, (3, 30,), (2, 20,), (1, 10,),], {
656            let mut v = Map::new(&env);
657            v.set(3, 30);
658            v.set(2, 20);
659            v.set(1, 10);
660            v
661        });
662    }
663
664    #[test]
665    fn test_empty() {
666        let env = Env::default();
667
668        let map: Map<(), ()> = map![&env];
669        assert_eq!(map.len(), 0);
670    }
671
672    #[test]
673    fn test_map_to_val() {
674        let env = Env::default();
675
676        let map = Map::<u32, ()>::from_array(&env, [(0, ()), (1, ()), (2, ()), (3, ())]);
677        let val: Val = map.clone().into_val(&env);
678        let rt: Map<u32, ()> = val.into_val(&env);
679
680        assert_eq!(map, rt);
681    }
682
683    #[test]
684    fn test_ref_map_to_val() {
685        let env = Env::default();
686
687        let map = Map::<u32, ()>::from_array(&env, [(0, ()), (1, ()), (2, ()), (3, ())]);
688        let val: Val = (&map).into_val(&env);
689        let rt: Map<u32, ()> = val.into_val(&env);
690
691        assert_eq!(map, rt);
692    }
693
694    #[test]
695    fn test_double_ref_map_to_val() {
696        let env = Env::default();
697
698        let map = Map::<u32, ()>::from_array(&env, [(0, ()), (1, ()), (2, ()), (3, ())]);
699        let val: Val = (&&map).into_val(&env);
700        let rt: Map<u32, ()> = val.into_val(&env);
701
702        assert_eq!(map, rt);
703    }
704
705    #[test]
706    fn test_raw_vals() {
707        let env = Env::default();
708
709        let map: Map<u32, bool> = map![&env, (1, true), (2, false)];
710        assert_eq!(map.len(), 2);
711        assert_eq!(map.get(1), Some(true));
712        assert_eq!(map.get(2), Some(false));
713        assert_eq!(map.get(3), None);
714    }
715
716    #[test]
717    fn test_iter() {
718        let env = Env::default();
719
720        let map: Map<(), ()> = map![&env];
721        let mut iter = map.iter();
722        assert_eq!(iter.len(), 0);
723        assert_eq!(iter.next(), None);
724        assert_eq!(iter.next(), None);
725
726        let map = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
727
728        let mut iter = map.iter();
729        assert_eq!(iter.len(), 5);
730        assert_eq!(iter.next(), Some((0, 0)));
731        assert_eq!(iter.len(), 4);
732        assert_eq!(iter.next(), Some((1, 10)));
733        assert_eq!(iter.len(), 3);
734        assert_eq!(iter.next(), Some((2, 20)));
735        assert_eq!(iter.len(), 2);
736        assert_eq!(iter.next(), Some((3, 30)));
737        assert_eq!(iter.len(), 1);
738        assert_eq!(iter.next(), Some((4, 40)));
739        assert_eq!(iter.len(), 0);
740        assert_eq!(iter.next(), None);
741        assert_eq!(iter.next(), None);
742
743        let mut iter = map.iter();
744        assert_eq!(iter.len(), 5);
745        assert_eq!(iter.next(), Some((0, 0)));
746        assert_eq!(iter.len(), 4);
747        assert_eq!(iter.next_back(), Some((4, 40)));
748        assert_eq!(iter.len(), 3);
749        assert_eq!(iter.next_back(), Some((3, 30)));
750        assert_eq!(iter.len(), 2);
751        assert_eq!(iter.next(), Some((1, 10)));
752        assert_eq!(iter.len(), 1);
753        assert_eq!(iter.next(), Some((2, 20)));
754        assert_eq!(iter.len(), 0);
755        assert_eq!(iter.next(), None);
756        assert_eq!(iter.next(), None);
757        assert_eq!(iter.next_back(), None);
758        assert_eq!(iter.next_back(), None);
759
760        let mut iter = map.iter().rev();
761        assert_eq!(iter.len(), 5);
762        assert_eq!(iter.next(), Some((4, 40)));
763        assert_eq!(iter.len(), 4);
764        assert_eq!(iter.next_back(), Some((0, 0)));
765        assert_eq!(iter.len(), 3);
766        assert_eq!(iter.next_back(), Some((1, 10)));
767        assert_eq!(iter.len(), 2);
768        assert_eq!(iter.next(), Some((3, 30)));
769        assert_eq!(iter.len(), 1);
770        assert_eq!(iter.next(), Some((2, 20)));
771        assert_eq!(iter.len(), 0);
772        assert_eq!(iter.next(), None);
773        assert_eq!(iter.next(), None);
774        assert_eq!(iter.next_back(), None);
775        assert_eq!(iter.next_back(), None);
776    }
777
778    #[test]
779    #[should_panic(expected = "ConversionError")]
780    fn test_iter_panic_on_key_conversion() {
781        let env = Env::default();
782
783        let map: Map<Val, Val> = map![&env, (1i64.into_val(&env), 2i32.into_val(&env)),];
784        let map: Val = map.into();
785        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
786
787        let mut iter = map.iter();
788        iter.next();
789    }
790
791    #[test]
792    #[should_panic(expected = "ConversionError")]
793    fn test_iter_panic_on_value_conversion() {
794        let env = Env::default();
795
796        let map: Map<Val, Val> = map![&env, (1i32.into_val(&env), 2i64.into_val(&env)),];
797        let map: Val = map.into();
798        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
799
800        let mut iter = map.iter();
801        iter.next();
802    }
803
804    #[test]
805    fn test_try_iter() {
806        let env = Env::default();
807
808        let map: Map<(), ()> = map![&env];
809        let mut iter = map.iter();
810        assert_eq!(iter.len(), 0);
811        assert_eq!(iter.next(), None);
812        assert_eq!(iter.next(), None);
813
814        let map = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
815
816        let mut iter = map.try_iter();
817        assert_eq!(iter.len(), 5);
818        assert_eq!(iter.next(), Some(Ok((0, 0))));
819        assert_eq!(iter.len(), 4);
820        assert_eq!(iter.next(), Some(Ok((1, 10))));
821        assert_eq!(iter.len(), 3);
822        assert_eq!(iter.next(), Some(Ok((2, 20))));
823        assert_eq!(iter.len(), 2);
824        assert_eq!(iter.next(), Some(Ok((3, 30))));
825        assert_eq!(iter.len(), 1);
826        assert_eq!(iter.next(), Some(Ok((4, 40))));
827        assert_eq!(iter.len(), 0);
828        assert_eq!(iter.next(), None);
829        assert_eq!(iter.next(), None);
830
831        let mut iter = map.try_iter();
832        assert_eq!(iter.len(), 5);
833        assert_eq!(iter.next(), Some(Ok((0, 0))));
834        assert_eq!(iter.len(), 4);
835        assert_eq!(iter.next_back(), Some(Ok((4, 40))));
836        assert_eq!(iter.len(), 3);
837        assert_eq!(iter.next_back(), Some(Ok((3, 30))));
838        assert_eq!(iter.len(), 2);
839        assert_eq!(iter.next(), Some(Ok((1, 10))));
840        assert_eq!(iter.len(), 1);
841        assert_eq!(iter.next(), Some(Ok((2, 20))));
842        assert_eq!(iter.len(), 0);
843        assert_eq!(iter.next(), None);
844        assert_eq!(iter.next(), None);
845        assert_eq!(iter.next_back(), None);
846        assert_eq!(iter.next_back(), None);
847
848        let mut iter = map.try_iter().rev();
849        assert_eq!(iter.len(), 5);
850        assert_eq!(iter.next(), Some(Ok((4, 40))));
851        assert_eq!(iter.len(), 4);
852        assert_eq!(iter.next_back(), Some(Ok((0, 0))));
853        assert_eq!(iter.len(), 3);
854        assert_eq!(iter.next_back(), Some(Ok((1, 10))));
855        assert_eq!(iter.len(), 2);
856        assert_eq!(iter.next(), Some(Ok((3, 30))));
857        assert_eq!(iter.len(), 1);
858        assert_eq!(iter.next(), Some(Ok((2, 20))));
859        assert_eq!(iter.len(), 0);
860        assert_eq!(iter.next(), None);
861        assert_eq!(iter.next(), None);
862        assert_eq!(iter.next_back(), None);
863        assert_eq!(iter.next_back(), None);
864    }
865
866    #[test]
867    fn test_iter_error_on_key_conversion() {
868        let env = Env::default();
869
870        let map: Map<Val, Val> = map![
871            &env,
872            (1i32.into_val(&env), 2i32.into_val(&env)),
873            (3i64.into_val(&env), 4i32.into_val(&env)),
874        ];
875        let map: Val = map.into();
876        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
877
878        let mut iter = map.try_iter();
879        assert_eq!(iter.next(), Some(Ok((1, 2))));
880        assert_eq!(iter.next(), Some(Err(ConversionError)));
881    }
882
883    #[test]
884    fn test_iter_error_on_value_conversion() {
885        let env = Env::default();
886
887        let map: Map<Val, Val> = map![
888            &env,
889            (1i32.into_val(&env), 2i32.into_val(&env)),
890            (3i32.into_val(&env), 4i64.into_val(&env)),
891        ];
892        let map: Val = map.into();
893        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
894
895        let mut iter = map.try_iter();
896        assert_eq!(iter.next(), Some(Ok((1, 2))));
897        assert_eq!(iter.next(), Some(Err(ConversionError)));
898    }
899
900    #[test]
901    fn test_keys() {
902        let env = Env::default();
903
904        let map = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
905        let keys = map.keys();
906        assert_eq!(keys, vec![&env, 0, 1, 2, 3, 4]);
907    }
908
909    #[test]
910    fn test_values() {
911        let env = Env::default();
912
913        let map = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
914        let values = map.values();
915        assert_eq!(values, vec![&env, 0, 10, 20, 30, 40]);
916    }
917
918    #[test]
919    fn test_from_array() {
920        let env = Env::default();
921
922        let map = Map::from_array(&env, [(0, 0), (1, 10), (2, 20), (3, 30), (4, 40)]);
923        assert_eq!(map, map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)]);
924
925        let map: Map<u32, u32> = Map::from_array(&env, []);
926        assert_eq!(map, map![&env]);
927    }
928
929    #[test]
930    fn test_contains_key() {
931        let env = Env::default();
932
933        let map: Map<u32, u32> = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
934
935        // contains all assigned keys
936        for i in 0..map.len() {
937            assert_eq!(true, map.contains_key(i));
938        }
939
940        // does not contain keys outside range
941        assert_eq!(map.contains_key(6), false);
942        assert_eq!(map.contains_key(u32::MAX), false);
943        assert_eq!(map.contains_key(8), false);
944    }
945
946    #[test]
947    fn test_is_empty() {
948        let env = Env::default();
949
950        let mut map: Map<u32, u32> = Map::new(&env);
951        assert_eq!(map.is_empty(), true);
952        map.set(0, 0);
953        assert_eq!(map.is_empty(), false);
954    }
955
956    #[test]
957    fn test_get() {
958        let env = Env::default();
959
960        let map: Map<u32, u32> = map![&env, (0, 0), (1, 10)];
961        assert_eq!(map.get(0), Some(0));
962        assert_eq!(map.get(1), Some(10));
963        assert_eq!(map.get(2), None);
964    }
965
966    #[test]
967    fn test_get_none_on_key_type_mismatch() {
968        let env = Env::default();
969
970        let map: Map<Val, Val> = map![
971            &env,
972            (1i32.into_val(&env), 2i32.into_val(&env)),
973            (3i64.into_val(&env), 4i32.into_val(&env)),
974        ];
975        let map: Val = map.into();
976        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
977        assert_eq!(map.get(1), Some(2));
978        assert_eq!(map.get(3), None);
979    }
980
981    #[test]
982    #[should_panic(expected = "ConversionError")]
983    fn test_get_panics_on_value_conversion() {
984        let env = Env::default();
985
986        let map: Map<Val, Val> = map![&env, (1i32.into_val(&env), 2i64.into_val(&env)),];
987        let map: Val = map.into();
988        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
989        let _ = map.get(1);
990    }
991
992    #[test]
993    fn test_try_get() {
994        let env = Env::default();
995
996        let map: Map<u32, u32> = map![&env, (0, 0), (1, 10)];
997        assert_eq!(map.try_get(0), Ok(Some(0)));
998        assert_eq!(map.try_get(1), Ok(Some(10)));
999        assert_eq!(map.try_get(2), Ok(None));
1000    }
1001
1002    #[test]
1003    fn test_try_get_none_on_key_type_mismatch() {
1004        let env = Env::default();
1005
1006        let map: Map<Val, Val> = map![
1007            &env,
1008            (1i32.into_val(&env), 2i32.into_val(&env)),
1009            (3i64.into_val(&env), 4i32.into_val(&env)),
1010        ];
1011        let map: Val = map.into();
1012        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
1013        assert_eq!(map.try_get(1), Ok(Some(2)));
1014        assert_eq!(map.try_get(3), Ok(None));
1015    }
1016
1017    #[test]
1018    fn test_try_get_errors_on_value_conversion() {
1019        let env = Env::default();
1020
1021        let map: Map<Val, Val> = map![
1022            &env,
1023            (1i32.into_val(&env), 2i32.into_val(&env)),
1024            (3i32.into_val(&env), 4i64.into_val(&env)),
1025        ];
1026        let map: Val = map.into();
1027        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
1028        assert_eq!(map.try_get(1), Ok(Some(2)));
1029        assert_eq!(map.try_get(3), Err(ConversionError));
1030    }
1031
1032    #[test]
1033    fn test_get_unchecked() {
1034        let env = Env::default();
1035
1036        let map: Map<u32, u32> = map![&env, (0, 0), (1, 10)];
1037        assert_eq!(map.get_unchecked(0), 0);
1038        assert_eq!(map.get_unchecked(1), 10);
1039    }
1040
1041    #[test]
1042    #[should_panic(expected = "HostError: Error(Object, MissingValue)")]
1043    fn test_get_unchecked_panics_on_key_type_mismatch() {
1044        let env = Env::default();
1045
1046        let map: Map<Val, Val> = map![&env, (1i64.into_val(&env), 2i32.into_val(&env)),];
1047        let map: Val = map.into();
1048        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
1049        let _ = map.get_unchecked(1);
1050    }
1051
1052    #[test]
1053    #[should_panic(expected = "ConversionError")]
1054    fn test_get_unchecked_panics_on_value_conversion() {
1055        let env = Env::default();
1056
1057        let map: Map<Val, Val> = map![&env, (1i32.into_val(&env), 2i64.into_val(&env)),];
1058        let map: Val = map.into();
1059        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
1060        let _ = map.get_unchecked(1);
1061    }
1062
1063    #[test]
1064    fn test_try_get_unchecked() {
1065        let env = Env::default();
1066
1067        let map: Map<u32, u32> = map![&env, (0, 0), (1, 10)];
1068        assert_eq!(map.get_unchecked(0), 0);
1069        assert_eq!(map.get_unchecked(1), 10);
1070    }
1071
1072    #[test]
1073    #[should_panic(expected = "HostError: Error(Object, MissingValue)")]
1074    fn test_try_get_unchecked_panics_on_key_type_mismatch() {
1075        let env = Env::default();
1076
1077        let map: Map<Val, Val> = map![&env, (1i64.into_val(&env), 2i32.into_val(&env)),];
1078        let map: Val = map.into();
1079        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
1080        let _ = map.try_get_unchecked(1);
1081    }
1082
1083    #[test]
1084    fn test_try_get_unchecked_errors_on_value_conversion() {
1085        let env = Env::default();
1086
1087        let map: Map<Val, Val> = map![
1088            &env,
1089            (1i32.into_val(&env), 2i32.into_val(&env)),
1090            (3i32.into_val(&env), 4i64.into_val(&env)),
1091        ];
1092        let map: Val = map.into();
1093        let map: Map<i32, i32> = map.try_into_val(&env).unwrap();
1094        assert_eq!(map.try_get_unchecked(1), Ok(2));
1095        assert_eq!(map.try_get_unchecked(3), Err(ConversionError));
1096    }
1097
1098    #[test]
1099    fn test_remove() {
1100        let env = Env::default();
1101
1102        let mut map: Map<u32, u32> = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
1103
1104        assert_eq!(map.len(), 5);
1105        assert_eq!(map.get(2), Some(20));
1106        assert_eq!(map.remove(2), Some(()));
1107        assert_eq!(map.get(2), None);
1108        assert_eq!(map.len(), 4);
1109
1110        // remove all items
1111        map.remove(0);
1112        map.remove(1);
1113        map.remove(3);
1114        map.remove(4);
1115        assert_eq!(map![&env], map);
1116
1117        // removing from empty map
1118        let mut map: Map<u32, u32> = map![&env];
1119        assert_eq!(map.remove(0), None);
1120        assert_eq!(map.remove(u32::MAX), None);
1121    }
1122
1123    #[test]
1124    fn test_remove_unchecked() {
1125        let env = Env::default();
1126
1127        let mut map: Map<u32, u32> = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
1128
1129        assert_eq!(map.len(), 5);
1130        assert_eq!(map.get(2), Some(20));
1131        map.remove_unchecked(2);
1132        assert_eq!(map.get(2), None);
1133        assert_eq!(map.len(), 4);
1134
1135        // remove all items
1136        map.remove_unchecked(0);
1137        map.remove_unchecked(1);
1138        map.remove_unchecked(3);
1139        map.remove_unchecked(4);
1140        assert_eq!(map![&env], map);
1141    }
1142
1143    #[test]
1144    #[should_panic(expected = "HostError: Error(Object, MissingValue)")]
1145    fn test_remove_unchecked_panic() {
1146        let env = Env::default();
1147        let mut map: Map<u32, u32> = map![&env, (0, 0), (1, 10), (2, 20), (3, 30), (4, 40)];
1148        map.remove_unchecked(100); // key does not exist
1149    }
1150}