Skip to main content

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