soroban_sdk/
vec.rs

1use core::{
2    borrow::Borrow,
3    cmp::Ordering,
4    convert::Infallible,
5    fmt::Debug,
6    iter::FusedIterator,
7    marker::PhantomData,
8    ops::{Bound, RangeBounds},
9};
10
11use crate::{
12    iter::{UnwrappedEnumerable, UnwrappedIter},
13    unwrap::{UnwrapInfallible, UnwrapOptimized},
14};
15
16use super::{
17    env::internal::{Env as _, EnvBase as _, VecObject},
18    ConversionError, Env, IntoVal, TryFromVal, TryIntoVal, Val,
19};
20
21#[cfg(doc)]
22use crate::{storage::Storage, Bytes, BytesN, Map};
23
24/// Create a [Vec] with the given items.
25///
26/// The first argument in the list must be a reference to an [Env], then the
27/// items follow.
28///
29/// ### Examples
30///
31/// ```
32/// use soroban_sdk::{Env, vec};
33///
34/// let env = Env::default();
35/// let vec = vec![&env, 0, 1, 2, 3];
36/// assert_eq!(vec.len(), 4);
37/// ```
38#[macro_export]
39macro_rules! vec {
40    ($env:expr $(,)?) => {
41        $crate::Vec::new($env)
42    };
43    ($env:expr, $($x:expr),+ $(,)?) => {
44        $crate::Vec::from_array($env, [$($x),+])
45    };
46}
47
48/// Vec is a sequential and indexable growable collection type.
49///
50/// Values are stored in the environment and are available to contract through
51/// the functions defined on Vec.  Values stored in the Vec are transmitted to
52/// the environment as [Val]s, and when retrieved from the Vec are
53/// transmitted back and converted from [Val] back into their type.
54///
55/// The values in a Vec are not guaranteed to be of type `T` and conversion will
56/// fail if they are not. Most functions on Vec have a `try_` variation that
57/// returns a `Result` that will be `Err` if the conversion fails. Functions
58/// 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 Vec that has been provided externally as a contract
63/// function argument, be aware there is no guarantee that all items in the Vec
64/// will be of type `T`. It may be necessary to validate all values, either
65/// before storing, or when loading with `try_` variation functions.
66///
67/// - When accessing and iterating over a Vec 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/// Functions with an `_unchecked` suffix will panic if called with indexes that
72/// are out-of-bounds.
73///
74/// To store `u8`s and binary data, use [Bytes]/[BytesN] instead.
75///
76/// Vec values can be stored as [Storage], or in other types like [Vec], [Map],
77/// etc.
78///
79/// ### Examples
80///
81/// ```
82/// use soroban_sdk::{vec, Env};
83///
84/// let env = Env::default();
85/// let vec = vec![&env, 0, 1, 2, 3];
86/// assert_eq!(vec.len(), 4);
87/// ```
88pub struct Vec<T> {
89    env: Env,
90    obj: VecObject,
91    _t: PhantomData<T>,
92}
93
94impl<T> Clone for Vec<T> {
95    fn clone(&self) -> Self {
96        Self {
97            env: self.env.clone(),
98            obj: self.obj,
99            _t: self._t,
100        }
101    }
102}
103
104impl<T> Eq for Vec<T> where T: IntoVal<Env, Val> + TryFromVal<Env, Val> {}
105
106impl<T> PartialEq for Vec<T>
107where
108    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
109{
110    fn eq(&self, other: &Self) -> bool {
111        self.partial_cmp(other) == Some(Ordering::Equal)
112    }
113}
114
115impl<T> PartialOrd for Vec<T>
116where
117    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
118{
119    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
120        Some(Ord::cmp(self, other))
121    }
122}
123
124impl<T> Ord for Vec<T>
125where
126    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
127{
128    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
129        #[cfg(not(target_family = "wasm"))]
130        if !self.env.is_same_env(&other.env) {
131            return ScVal::from(self).cmp(&ScVal::from(other));
132        }
133        let v = self
134            .env
135            .obj_cmp(self.obj.to_val(), other.obj.to_val())
136            .unwrap_infallible();
137        v.cmp(&0)
138    }
139}
140
141impl<T> Debug for Vec<T>
142where
143    T: IntoVal<Env, Val> + TryFromVal<Env, Val> + Debug + Clone,
144    T::Error: Debug,
145{
146    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
147        write!(f, "Vec(")?;
148        let mut iter = self.try_iter();
149        if let Some(x) = iter.next() {
150            write!(f, "{:?}", x)?;
151        }
152        for x in iter {
153            write!(f, ", {:?}", x)?;
154        }
155        write!(f, ")")?;
156        Ok(())
157    }
158}
159
160impl<T> TryFromVal<Env, Vec<T>> for Vec<Val> {
161    type Error = Infallible;
162
163    fn try_from_val(env: &Env, v: &Vec<T>) -> Result<Self, Self::Error> {
164        Ok(unsafe { Vec::unchecked_new(env.clone(), v.obj) })
165    }
166}
167
168// This conflicts with the previous definition unless we add the spurious &,
169// which is not .. great. Maybe don't define this particular blanket, or add
170// a to_other<T>() method?
171impl<T> TryFromVal<Env, &Vec<Val>> for Vec<T> {
172    type Error = Infallible;
173
174    fn try_from_val(env: &Env, v: &&Vec<Val>) -> Result<Self, Self::Error> {
175        Ok(unsafe { Vec::unchecked_new(env.clone(), v.obj) })
176    }
177}
178
179impl<T> TryFromVal<Env, VecObject> for Vec<T>
180where
181    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
182{
183    type Error = Infallible;
184
185    #[inline(always)]
186    fn try_from_val(env: &Env, obj: &VecObject) -> Result<Self, Self::Error> {
187        Ok(unsafe { Vec::<T>::unchecked_new(env.clone(), *obj) })
188    }
189}
190
191impl<T> TryFromVal<Env, Val> for Vec<T>
192where
193    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
194{
195    type Error = ConversionError;
196
197    #[inline(always)]
198    fn try_from_val(env: &Env, val: &Val) -> Result<Self, Self::Error> {
199        Ok(VecObject::try_from_val(env, val)?
200            .try_into_val(env)
201            .unwrap_infallible())
202    }
203}
204
205impl<T> TryFromVal<Env, Vec<T>> for Val {
206    type Error = ConversionError;
207
208    fn try_from_val(_env: &Env, v: &Vec<T>) -> Result<Self, Self::Error> {
209        Ok(v.to_val())
210    }
211}
212
213impl<T> From<Vec<T>> for Val
214where
215    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
216{
217    #[inline(always)]
218    fn from(v: Vec<T>) -> Self {
219        v.obj.into()
220    }
221}
222
223impl<T> From<Vec<T>> for VecObject
224where
225    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
226{
227    #[inline(always)]
228    fn from(v: Vec<T>) -> Self {
229        v.obj
230    }
231}
232
233#[cfg(not(target_family = "wasm"))]
234use super::xdr::{ScVal, ScVec, VecM};
235
236#[cfg(not(target_family = "wasm"))]
237impl<T> From<&Vec<T>> for ScVal {
238    fn from(v: &Vec<T>) -> Self {
239        // This conversion occurs only in test utilities, and theoretically all
240        // values should convert to an ScVal because the Env won't let the host
241        // type to exist otherwise, unwrapping. Even if there are edge cases
242        // that don't, this is a trade off for a better test developer
243        // experience.
244        ScVal::try_from_val(&v.env, &v.obj.to_val()).unwrap()
245    }
246}
247
248#[cfg(not(target_family = "wasm"))]
249impl<T> From<&Vec<T>> for ScVec {
250    fn from(v: &Vec<T>) -> Self {
251        if let ScVal::Vec(Some(vec)) = ScVal::try_from(v).unwrap() {
252            vec
253        } else {
254            panic!("expected ScVec")
255        }
256    }
257}
258
259#[cfg(not(target_family = "wasm"))]
260impl<T> From<Vec<T>> for VecM<ScVal> {
261    fn from(v: Vec<T>) -> Self {
262        ScVec::from(v).0
263    }
264}
265
266#[cfg(not(target_family = "wasm"))]
267impl<T> From<Vec<T>> for ScVal {
268    fn from(v: Vec<T>) -> Self {
269        (&v).into()
270    }
271}
272
273#[cfg(not(target_family = "wasm"))]
274impl<T> From<Vec<T>> for ScVec {
275    fn from(v: Vec<T>) -> Self {
276        (&v).into()
277    }
278}
279
280#[cfg(not(target_family = "wasm"))]
281impl<T> TryFromVal<Env, ScVal> for Vec<T>
282where
283    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
284{
285    type Error = ConversionError;
286    fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, ConversionError> {
287        Ok(VecObject::try_from_val(env, &Val::try_from_val(env, val)?)?
288            .try_into_val(env)
289            .unwrap_infallible())
290    }
291}
292
293#[cfg(not(target_family = "wasm"))]
294impl<T> TryFromVal<Env, ScVec> for Vec<T>
295where
296    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
297{
298    type Error = ConversionError;
299    fn try_from_val(env: &Env, val: &ScVec) -> Result<Self, Self::Error> {
300        ScVal::Vec(Some(val.clone())).try_into_val(env)
301    }
302}
303
304#[cfg(not(target_family = "wasm"))]
305impl<T> TryFromVal<Env, VecM<ScVal>> for Vec<T>
306where
307    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
308{
309    type Error = ConversionError;
310    fn try_from_val(env: &Env, val: &VecM<ScVal>) -> Result<Self, Self::Error> {
311        ScVec(val.clone()).try_into_val(env)
312    }
313}
314
315impl<T> Vec<T> {
316    #[inline(always)]
317    pub(crate) unsafe fn unchecked_new(env: Env, obj: VecObject) -> Self {
318        Self {
319            env,
320            obj,
321            _t: PhantomData,
322        }
323    }
324
325    pub fn env(&self) -> &Env {
326        &self.env
327    }
328
329    pub fn as_val(&self) -> &Val {
330        self.obj.as_val()
331    }
332
333    pub fn to_val(&self) -> Val {
334        self.obj.to_val()
335    }
336
337    pub fn as_object(&self) -> &VecObject {
338        &self.obj
339    }
340
341    pub fn to_object(&self) -> VecObject {
342        self.obj
343    }
344
345    pub fn to_vals(&self) -> Vec<Val> {
346        unsafe { Vec::<Val>::unchecked_new(self.env().clone(), self.obj) }
347    }
348}
349
350impl<T> Vec<T>
351where
352    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
353{
354    /// Create an empty Vec.
355    #[inline(always)]
356    pub fn new(env: &Env) -> Vec<T> {
357        unsafe { Self::unchecked_new(env.clone(), env.vec_new().unwrap_infallible()) }
358    }
359
360    /// Create a Vec from the array of items.
361    #[inline(always)]
362    pub fn from_array<const N: usize>(env: &Env, items: [T; N]) -> Vec<T> {
363        let mut tmp: [Val; N] = [Val::VOID.to_val(); N];
364        for (dst, src) in tmp.iter_mut().zip(items.iter()) {
365            *dst = src.into_val(env)
366        }
367        let vec = env.vec_new_from_slice(&tmp).unwrap_infallible();
368        unsafe { Self::unchecked_new(env.clone(), vec) }
369    }
370
371    /// Create a Vec from the slice of items.
372    #[inline(always)]
373    pub fn from_slice(env: &Env, items: &[T]) -> Vec<T>
374    where
375        T: Clone,
376    {
377        let mut vec = Vec::new(env);
378        vec.extend_from_slice(items);
379        vec
380    }
381
382    /// Returns the item at the position or None if out-of-bounds.
383    ///
384    /// ### Panics
385    ///
386    /// If the value at the position cannot be converted to type T.
387    #[inline(always)]
388    pub fn get(&self, i: u32) -> Option<T> {
389        self.try_get(i).unwrap_optimized()
390    }
391
392    /// Returns the item at the position or None if out-of-bounds.
393    ///
394    /// ### Errors
395    ///
396    /// If the value at the position cannot be converted to type T.
397    #[inline(always)]
398    pub fn try_get(&self, i: u32) -> Result<Option<T>, T::Error> {
399        if i < self.len() {
400            self.try_get_unchecked(i).map(|val| Some(val))
401        } else {
402            Ok(None)
403        }
404    }
405
406    /// Returns the item at the position.
407    ///
408    /// ### Panics
409    ///
410    /// If the position is out-of-bounds.
411    ///
412    /// If the value at the position cannot be converted to type T.
413    #[inline(always)]
414    pub fn get_unchecked(&self, i: u32) -> T {
415        self.try_get_unchecked(i).unwrap_optimized()
416    }
417
418    /// Returns the item at the position.
419    ///
420    /// ### Errors
421    ///
422    /// If the value at the position cannot be converted to type T.
423    ///
424    /// ### Panics
425    ///
426    /// If the position is out-of-bounds.
427    #[inline(always)]
428    pub fn try_get_unchecked(&self, i: u32) -> Result<T, T::Error> {
429        let env = self.env();
430        let val = env.vec_get(self.obj, i.into()).unwrap_infallible();
431        T::try_from_val(env, &val)
432    }
433
434    /// Sets the item at the position with new value.
435    ///
436    /// ### Panics
437    ///
438    /// If the position is out-of-bounds.
439    #[inline(always)]
440    pub fn set(&mut self, i: u32, v: T) {
441        let env = self.env();
442        self.obj = env
443            .vec_put(self.obj, i.into(), v.into_val(env))
444            .unwrap_infallible();
445    }
446
447    /// Removes the item at the position.
448    ///
449    /// Returns `None` if out-of-bounds.
450    #[inline(always)]
451    pub fn remove(&mut self, i: u32) -> Option<()> {
452        if i < self.len() {
453            self.remove_unchecked(i);
454            Some(())
455        } else {
456            None
457        }
458    }
459
460    /// Removes the item at the position.
461    ///
462    /// ### Panics
463    ///
464    /// If the position is out-of-bounds.
465    #[inline(always)]
466    pub fn remove_unchecked(&mut self, i: u32) {
467        let env = self.env();
468        self.obj = env.vec_del(self.obj, i.into()).unwrap_infallible();
469    }
470
471    /// Adds the item to the front.
472    ///
473    /// Increases the length by one, shifts all items up by one, and puts the
474    /// item in the first position.
475    #[inline(always)]
476    pub fn push_front(&mut self, x: T) {
477        let env = self.env();
478        self.obj = env
479            .vec_push_front(self.obj, x.into_val(env))
480            .unwrap_infallible();
481    }
482
483    /// Removes and returns the first item or None if empty.
484    ///
485    /// ### Panics
486    ///
487    /// If the value at the first position cannot be converted to type T.
488    #[inline(always)]
489    pub fn pop_front(&mut self) -> Option<T> {
490        self.try_pop_front().unwrap_optimized()
491    }
492
493    /// Removes and returns the first item or None if empty.
494    ///
495    /// ### Errors
496    ///
497    /// If the value at the first position cannot be converted to type T.
498    #[inline(always)]
499    pub fn try_pop_front(&mut self) -> Result<Option<T>, T::Error> {
500        if self.is_empty() {
501            Ok(None)
502        } else {
503            self.try_pop_front_unchecked().map(|val| Some(val))
504        }
505    }
506
507    /// Removes and returns the first item.
508    ///
509    /// ### Panics
510    ///
511    /// If the vec is empty.
512    ///
513    /// If the value at the first position cannot be converted to type T.
514    #[inline(always)]
515    pub fn pop_front_unchecked(&mut self) -> T {
516        self.try_pop_front_unchecked().unwrap_optimized()
517    }
518
519    /// Removes and returns the first item.
520    ///
521    /// ### Errors
522    ///
523    /// If the value at the first position cannot be converted to type T.
524    ///
525    /// ### Panics
526    ///
527    /// If the vec is empty.
528    #[inline(always)]
529    pub fn try_pop_front_unchecked(&mut self) -> Result<T, T::Error> {
530        let last = self.try_first_unchecked()?;
531        let env = self.env();
532        self.obj = env.vec_pop_front(self.obj).unwrap_infallible();
533        Ok(last)
534    }
535
536    /// Adds the item to the back.
537    ///
538    /// Increases the length by one and puts the item in the last position.
539    #[inline(always)]
540    pub fn push_back(&mut self, x: T) {
541        let env = self.env();
542        self.obj = env
543            .vec_push_back(self.obj, x.into_val(env))
544            .unwrap_infallible();
545    }
546
547    /// Removes and returns the last item or None if empty.
548    ///
549    /// ### Panics
550    ///
551    /// If the value at the last position cannot be converted to type T.
552    #[inline(always)]
553    pub fn pop_back(&mut self) -> Option<T> {
554        self.try_pop_back().unwrap_optimized()
555    }
556
557    /// Removes and returns the last item or None if empty.
558    ///
559    /// ### Errors
560    ///
561    /// If the value at the last position cannot be converted to type T.
562    #[inline(always)]
563    pub fn try_pop_back(&mut self) -> Result<Option<T>, T::Error> {
564        if self.is_empty() {
565            Ok(None)
566        } else {
567            self.try_pop_back_unchecked().map(|val| Some(val))
568        }
569    }
570
571    /// Removes and returns the last item.
572    ///
573    /// ### Panics
574    ///
575    /// If the vec is empty.
576    ///
577    /// If the value at the last position cannot be converted to type T.
578    #[inline(always)]
579    pub fn pop_back_unchecked(&mut self) -> T {
580        self.try_pop_back_unchecked().unwrap_optimized()
581    }
582
583    /// Removes and returns the last item.
584    ///
585    /// ### Errors
586    ///
587    /// If the value at the last position cannot be converted to type T.
588    ///
589    /// ### Panics
590    ///
591    /// If the vec is empty.
592    #[inline(always)]
593    pub fn try_pop_back_unchecked(&mut self) -> Result<T, T::Error> {
594        let last = self.try_last_unchecked()?;
595        let env = self.env();
596        self.obj = env.vec_pop_back(self.obj).unwrap_infallible();
597        Ok(last)
598    }
599
600    /// Returns the first item or None if empty.
601    ///
602    /// ### Panics
603    ///
604    /// If the value at the first position cannot be converted to type T.
605    #[inline(always)]
606    pub fn first(&self) -> Option<T> {
607        self.try_first().unwrap_optimized()
608    }
609
610    /// Returns the first item or None if empty.
611    ///
612    /// ### Errors
613    ///
614    /// If the value at the first position cannot be converted to type T.
615    #[inline(always)]
616    pub fn try_first(&self) -> Result<Option<T>, T::Error> {
617        if self.is_empty() {
618            Ok(None)
619        } else {
620            self.try_first_unchecked().map(|val| Some(val))
621        }
622    }
623
624    /// Returns the first item.
625    ///
626    /// ### Panics
627    ///
628    /// If the vec is empty.
629    ///
630    /// If the value at the first position cannot be converted to type T.
631    #[inline(always)]
632    pub fn first_unchecked(&self) -> T {
633        self.try_first_unchecked().unwrap_optimized()
634    }
635
636    /// Returns the first item.
637    ///
638    /// ### Errors
639    ///
640    /// If the value at the first position cannot be converted to type T.
641    ///
642    /// ### Panics
643    ///
644    /// If the vec is empty.
645    #[inline(always)]
646    pub fn try_first_unchecked(&self) -> Result<T, T::Error> {
647        let env = &self.env;
648        let val = env.vec_front(self.obj).unwrap_infallible();
649        T::try_from_val(env, &val)
650    }
651
652    /// Returns the last item or None if empty.
653    ///
654    /// ### Panics
655    ///
656    /// If the value at the last position cannot be converted to type T.
657    #[inline(always)]
658    pub fn last(&self) -> Option<T> {
659        self.try_last().unwrap_optimized()
660    }
661
662    /// Returns the last item or None if empty.
663    ///
664    /// ### Errors
665    ///
666    /// If the value at the last position cannot be converted to type T.
667    #[inline(always)]
668    pub fn try_last(&self) -> Result<Option<T>, T::Error> {
669        if self.is_empty() {
670            Ok(None)
671        } else {
672            self.try_last_unchecked().map(|val| Some(val))
673        }
674    }
675
676    /// Returns the last item.
677    ///
678    /// ### Panics
679    ///
680    /// If the vec is empty.
681    ///
682    /// If the value at the last position cannot be converted to type T.
683    #[inline(always)]
684    pub fn last_unchecked(&self) -> T {
685        self.try_last_unchecked().unwrap_optimized()
686    }
687
688    /// Returns the last item.
689    ///
690    /// ### Errors
691    ///
692    /// If the value at the last position cannot be converted to type T.
693    ///
694    /// ### Panics
695    ///
696    /// If the vec is empty.
697    #[inline(always)]
698    pub fn try_last_unchecked(&self) -> Result<T, T::Error> {
699        let env = self.env();
700        let val = env.vec_back(self.obj).unwrap_infallible();
701        T::try_from_val(env, &val)
702    }
703
704    /// Inserts an item at the position.
705    ///
706    /// ### Panics
707    ///
708    /// If the position is out-of-bounds.
709    #[inline(always)]
710    pub fn insert(&mut self, i: u32, x: T) {
711        let env = self.env();
712        self.obj = env
713            .vec_insert(self.obj, i.into(), x.into_val(env))
714            .unwrap_infallible();
715    }
716
717    /// Append the items.
718    #[inline(always)]
719    pub fn append(&mut self, other: &Vec<T>) {
720        let env = self.env();
721        self.obj = env.vec_append(self.obj, other.obj).unwrap_infallible();
722    }
723
724    /// Extend with the items in the array.
725    #[inline(always)]
726    pub fn extend_from_array<const N: usize>(&mut self, items: [T; N]) {
727        self.append(&Self::from_array(&self.env, items))
728    }
729
730    /// Extend with the items in the slice.
731    #[inline(always)]
732    pub fn extend_from_slice(&mut self, items: &[T])
733    where
734        T: Clone,
735    {
736        for item in items {
737            self.push_back(item.clone());
738        }
739    }
740}
741
742impl<T> Vec<T> {
743    /// Returns a subset of the bytes as defined by the start and end bounds of
744    /// the range.
745    ///
746    /// ### Panics
747    ///
748    /// If the range is out-of-bounds.
749    #[must_use]
750    pub fn slice(&self, r: impl RangeBounds<u32>) -> Self {
751        let start_bound = match r.start_bound() {
752            Bound::Included(s) => *s,
753            Bound::Excluded(s) => *s + 1,
754            Bound::Unbounded => 0,
755        };
756        let end_bound = match r.end_bound() {
757            Bound::Included(s) => *s + 1,
758            Bound::Excluded(s) => *s,
759            Bound::Unbounded => self.len(),
760        };
761        let env = self.env();
762        let obj = env
763            .vec_slice(self.obj, start_bound.into(), end_bound.into())
764            .unwrap_infallible();
765        unsafe { Self::unchecked_new(env.clone(), obj) }
766    }
767
768    /// Returns copy of the vec shuffled using the NOT-SECURE PRNG.
769    ///
770    /// In tests, must be called from within a running contract.
771    ///
772    /// # Warning
773    ///
774    /// **The pseudo-random generator used to perform the shuffle is not
775    /// suitable for security-sensitive work.**
776    pub fn shuffle(&mut self) {
777        let env = self.env();
778        env.prng().shuffle(self);
779    }
780
781    /// Returns copy of the vec shuffled using the NOT-SECURE PRNG.
782    ///
783    /// In tests, must be called from within a running contract.
784    ///
785    /// # Warning
786    ///
787    /// **The pseudo-random generator used to perform the shuffle is not
788    /// suitable for security-sensitive work.**
789    #[must_use]
790    pub fn to_shuffled(&self) -> Self {
791        let mut copy = self.clone();
792        copy.shuffle();
793        copy
794    }
795
796    /// Returns true if the vec is empty and contains no items.
797    #[inline(always)]
798    pub fn is_empty(&self) -> bool {
799        self.len() == 0
800    }
801
802    /// Returns the number of items in the vec.
803    #[inline(always)]
804    pub fn len(&self) -> u32 {
805        self.env.vec_len(self.obj).unwrap_infallible().into()
806    }
807}
808
809impl<T> Vec<T>
810where
811    T: IntoVal<Env, Val>,
812{
813    /// Returns true if the Vec contains the item.
814    #[inline(always)]
815    pub fn contains(&self, item: impl Borrow<T>) -> bool {
816        let env = self.env();
817        let val = item.borrow().into_val(env);
818        !env.vec_first_index_of(self.obj, val)
819            .unwrap_infallible()
820            .is_void()
821    }
822
823    /// Returns the index of the first occurrence of the item.
824    ///
825    /// If the item cannot be found [None] is returned.
826    #[inline(always)]
827    pub fn first_index_of(&self, item: impl Borrow<T>) -> Option<u32> {
828        let env = self.env();
829        let val = item.borrow().into_val(env);
830        env.vec_first_index_of(self.obj, val)
831            .unwrap_infallible()
832            .try_into_val(env)
833            .unwrap()
834    }
835
836    /// Returns the index of the last occurrence of the item.
837    ///
838    /// If the item cannot be found [None] is returned.
839    #[inline(always)]
840    pub fn last_index_of(&self, item: impl Borrow<T>) -> Option<u32> {
841        let env = self.env();
842        let val = item.borrow().into_val(env);
843        env.vec_last_index_of(self.obj, val)
844            .unwrap_infallible()
845            .try_into_val(env)
846            .unwrap()
847    }
848
849    /// Returns the index of an occurrence of the item in an already sorted
850    /// [Vec], or the index of where the item can be inserted to keep the [Vec]
851    /// sorted.
852    ///
853    /// If the item is found, [Result::Ok] is returned containing the index of
854    /// the item.
855    ///
856    /// If the item is not found, [Result::Err] is returned containing the index
857    /// of where the item could be inserted to retain the sorted ordering.
858    #[inline(always)]
859    pub fn binary_search(&self, item: impl Borrow<T>) -> Result<u32, u32> {
860        let env = self.env();
861        let val = item.borrow().into_val(env);
862        let high_low = env.vec_binary_search(self.obj, val).unwrap_infallible();
863        let high: u32 = (high_low >> u32::BITS) as u32;
864        let low: u32 = high_low as u32;
865        if high == 1 {
866            Ok(low)
867        } else {
868            Err(low)
869        }
870    }
871}
872
873impl<T> Vec<Vec<T>>
874where
875    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
876    T: Clone,
877{
878    #[inline(always)]
879    pub fn concat(&self) -> Vec<T> {
880        let mut concatenated = vec![self.env()];
881        for vec in self.iter() {
882            concatenated.append(&vec);
883        }
884        concatenated
885    }
886}
887
888impl<T> IntoIterator for Vec<T>
889where
890    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
891{
892    type Item = T;
893    type IntoIter = UnwrappedIter<VecTryIter<T>, T, T::Error>;
894
895    fn into_iter(self) -> Self::IntoIter {
896        VecTryIter::new(self).unwrapped()
897    }
898}
899
900impl<T> IntoIterator for &Vec<T>
901where
902    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
903{
904    type Item = T;
905    type IntoIter = UnwrappedIter<VecTryIter<T>, T, T::Error>;
906
907    fn into_iter(self) -> Self::IntoIter {
908        self.clone().into_iter()
909    }
910}
911
912impl<T> Vec<T>
913where
914    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
915{
916    #[inline(always)]
917    pub fn iter(&self) -> UnwrappedIter<VecTryIter<T>, T, T::Error>
918    where
919        T: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
920        T::Error: Debug,
921    {
922        self.try_iter().unwrapped()
923    }
924
925    #[inline(always)]
926    pub fn try_iter(&self) -> VecTryIter<T>
927    where
928        T: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
929    {
930        VecTryIter::new(self.clone())
931    }
932
933    #[inline(always)]
934    pub fn into_try_iter(self) -> VecTryIter<T>
935    where
936        T: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
937        T::Error: Debug,
938    {
939        VecTryIter::new(self.clone())
940    }
941}
942
943#[derive(Clone)]
944pub struct VecTryIter<T> {
945    vec: Vec<T>,
946    start: u32, // inclusive
947    end: u32,   // exclusive
948}
949
950impl<T> VecTryIter<T> {
951    fn new(vec: Vec<T>) -> Self {
952        Self {
953            start: 0,
954            end: vec.len(),
955            vec,
956        }
957    }
958
959    fn into_vec(self) -> Vec<T> {
960        self.vec.slice(self.start..self.end)
961    }
962}
963
964impl<T> Iterator for VecTryIter<T>
965where
966    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
967{
968    type Item = Result<T, T::Error>;
969
970    fn next(&mut self) -> Option<Self::Item> {
971        if self.start < self.end {
972            let val = self.vec.try_get_unchecked(self.start);
973            self.start += 1;
974            Some(val)
975        } else {
976            None
977        }
978    }
979
980    fn size_hint(&self) -> (usize, Option<usize>) {
981        let len = (self.end - self.start) as usize;
982        (len, Some(len))
983    }
984
985    // TODO: Implement other functions as optimizations since the iterator is
986    // backed by an indexable collection.
987}
988
989impl<T> DoubleEndedIterator for VecTryIter<T>
990where
991    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
992{
993    fn next_back(&mut self) -> Option<Self::Item> {
994        if self.start < self.end {
995            let val = self.vec.try_get_unchecked(self.end - 1);
996            self.end -= 1;
997            Some(val)
998        } else {
999            None
1000        }
1001    }
1002
1003    // TODO: Implement other functions as optimizations since the iterator is
1004    // backed by an indexable collection.
1005}
1006
1007impl<T> FusedIterator for VecTryIter<T> where T: IntoVal<Env, Val> + TryFromVal<Env, Val> {}
1008
1009impl<T> ExactSizeIterator for VecTryIter<T>
1010where
1011    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
1012{
1013    fn len(&self) -> usize {
1014        (self.end - self.start) as usize
1015    }
1016}
1017
1018#[cfg(test)]
1019mod test {
1020    use super::*;
1021
1022    #[test]
1023    fn test_vec_macro() {
1024        let env = Env::default();
1025        assert_eq!(vec![&env], Vec::<i32>::new(&env));
1026        assert_eq!(vec![&env,], Vec::<i32>::new(&env));
1027        assert_eq!(vec![&env, 1], {
1028            let mut v = Vec::new(&env);
1029            v.push_back(1);
1030            v
1031        });
1032        assert_eq!(vec![&env, 1,], {
1033            let mut v = Vec::new(&env);
1034            v.push_back(1);
1035            v
1036        });
1037        assert_eq!(vec![&env, 3, 2, 1,], {
1038            let mut v = Vec::new(&env);
1039            v.push_back(3);
1040            v.push_back(2);
1041            v.push_back(1);
1042            v
1043        });
1044    }
1045
1046    #[test]
1047    fn test_vec_raw_val_type() {
1048        let env = Env::default();
1049
1050        let mut vec = Vec::<u32>::new(&env);
1051        assert_eq!(vec.len(), 0);
1052        vec.push_back(10);
1053        assert_eq!(vec.len(), 1);
1054        vec.push_back(20);
1055        assert_eq!(vec.len(), 2);
1056        vec.push_back(30);
1057        assert_eq!(vec.len(), 3);
1058
1059        let vec_ref = &vec;
1060        assert_eq!(vec_ref.len(), 3);
1061
1062        let mut vec_copy = vec.clone();
1063        assert!(vec == vec_copy);
1064        assert_eq!(vec_copy.len(), 3);
1065        vec_copy.push_back(40);
1066        assert_eq!(vec_copy.len(), 4);
1067        assert!(vec != vec_copy);
1068
1069        assert_eq!(vec.len(), 3);
1070        assert_eq!(vec_ref.len(), 3);
1071
1072        _ = vec_copy.pop_back_unchecked();
1073        assert!(vec == vec_copy);
1074    }
1075
1076    #[test]
1077    fn test_vec_env_val_type() {
1078        let env = Env::default();
1079
1080        let mut vec = Vec::<i64>::new(&env);
1081        assert_eq!(vec.len(), 0);
1082        vec.push_back(-10);
1083        assert_eq!(vec.len(), 1);
1084        vec.push_back(20);
1085        assert_eq!(vec.len(), 2);
1086        vec.push_back(-30);
1087        assert_eq!(vec.len(), 3);
1088
1089        let vec_ref = &vec;
1090        assert_eq!(vec_ref.len(), 3);
1091
1092        let mut vec_copy = vec.clone();
1093        assert!(vec == vec_copy);
1094        assert_eq!(vec_copy.len(), 3);
1095        vec_copy.push_back(40);
1096        assert_eq!(vec_copy.len(), 4);
1097        assert!(vec != vec_copy);
1098
1099        assert_eq!(vec.len(), 3);
1100        assert_eq!(vec_ref.len(), 3);
1101
1102        _ = vec_copy.pop_back_unchecked();
1103        assert!(vec == vec_copy);
1104    }
1105
1106    #[test]
1107    fn test_vec_to_vals() {
1108        let env = Env::default();
1109        let vec = vec![&env, 0, 1, 2, 3, 4];
1110        let vals = vec.to_vals();
1111        assert_eq!(
1112            vals,
1113            vec![
1114                &env,
1115                Val::from_i32(0).to_val(),
1116                Val::from_i32(1).to_val(),
1117                Val::from_i32(2).to_val(),
1118                Val::from_i32(3).to_val(),
1119                Val::from_i32(4).to_val(),
1120            ]
1121        );
1122    }
1123
1124    #[test]
1125    fn test_vec_recursive() {
1126        let env = Env::default();
1127
1128        let mut vec_inner = Vec::<i64>::new(&env);
1129        vec_inner.push_back(-10);
1130        assert_eq!(vec_inner.len(), 1);
1131
1132        let mut vec_outer = Vec::<Vec<i64>>::new(&env);
1133        vec_outer.push_back(vec_inner);
1134        assert_eq!(vec_outer.len(), 1);
1135    }
1136
1137    #[test]
1138    fn test_vec_concat() {
1139        let env = Env::default();
1140        let vec_1: Vec<i64> = vec![&env, 1, 2, 3];
1141        let vec_2: Vec<i64> = vec![&env, 4, 5, 6];
1142        let vec = vec![&env, vec_1, vec_2].concat();
1143        assert_eq!(vec, vec![&env, 1, 2, 3, 4, 5, 6]);
1144    }
1145
1146    #[test]
1147    fn test_vec_slice() {
1148        let env = Env::default();
1149
1150        let vec = vec![&env, 0, 1, 2, 3, 4];
1151        assert_eq!(vec.len(), 5);
1152
1153        let slice = vec.slice(..);
1154        assert_eq!(slice, vec![&env, 0, 1, 2, 3, 4]);
1155
1156        let slice = vec.slice(0..5);
1157        assert_eq!(slice, vec![&env, 0, 1, 2, 3, 4]);
1158
1159        let slice = vec.slice(0..=4);
1160        assert_eq!(slice, vec![&env, 0, 1, 2, 3, 4]);
1161
1162        let slice = vec.slice(1..);
1163        assert_eq!(slice, vec![&env, 1, 2, 3, 4]);
1164
1165        let slice = vec.slice(..4);
1166        assert_eq!(slice, vec![&env, 0, 1, 2, 3]);
1167
1168        let slice = vec.slice(..=3);
1169        assert_eq!(slice, vec![&env, 0, 1, 2, 3]);
1170
1171        let slice = vec.slice(1..4);
1172        assert_eq!(slice, vec![&env, 1, 2, 3]);
1173
1174        let slice = vec.slice(1..=3);
1175        assert_eq!(slice, vec![&env, 1, 2, 3]);
1176
1177        // An exclusive start is technically possible due to the lack of
1178        // constraints in the RangeBounds trait, however this is unlikely to
1179        // happen since no syntax shorthand exists for it.
1180        let slice = vec.slice((Bound::Excluded(0), Bound::Included(3)));
1181        assert_eq!(slice, vec![&env, 1, 2, 3]);
1182        let slice = vec.slice((Bound::Excluded(0), Bound::Excluded(3)));
1183        assert_eq!(slice, vec![&env, 1, 2]);
1184    }
1185
1186    #[test]
1187    fn test_vec_iter() {
1188        let env = Env::default();
1189
1190        let vec: Vec<()> = vec![&env];
1191        let mut iter = vec.iter();
1192        assert_eq!(iter.len(), 0);
1193        assert_eq!(iter.next(), None);
1194        assert_eq!(iter.next(), None);
1195
1196        let vec = vec![&env, 0, 1, 2, 3, 4];
1197
1198        let mut iter = vec.iter();
1199        assert_eq!(iter.len(), 5);
1200        assert_eq!(iter.next(), Some(0));
1201        assert_eq!(iter.len(), 4);
1202        assert_eq!(iter.next(), Some(1));
1203        assert_eq!(iter.len(), 3);
1204        assert_eq!(iter.next(), Some(2));
1205        assert_eq!(iter.len(), 2);
1206        assert_eq!(iter.next(), Some(3));
1207        assert_eq!(iter.len(), 1);
1208        assert_eq!(iter.next(), Some(4));
1209        assert_eq!(iter.len(), 0);
1210        assert_eq!(iter.next(), None);
1211        assert_eq!(iter.next(), None);
1212
1213        let mut iter = vec.iter();
1214        assert_eq!(iter.len(), 5);
1215        assert_eq!(iter.next(), Some(0));
1216        assert_eq!(iter.len(), 4);
1217        assert_eq!(iter.next_back(), Some(4));
1218        assert_eq!(iter.len(), 3);
1219        assert_eq!(iter.next_back(), Some(3));
1220        assert_eq!(iter.len(), 2);
1221        assert_eq!(iter.next(), Some(1));
1222        assert_eq!(iter.len(), 1);
1223        assert_eq!(iter.next(), Some(2));
1224        assert_eq!(iter.len(), 0);
1225        assert_eq!(iter.next(), None);
1226        assert_eq!(iter.next(), None);
1227        assert_eq!(iter.next_back(), None);
1228        assert_eq!(iter.next_back(), None);
1229
1230        let mut iter = vec.iter().rev();
1231        assert_eq!(iter.next(), Some(4));
1232        assert_eq!(iter.next_back(), Some(0));
1233        assert_eq!(iter.next_back(), Some(1));
1234        assert_eq!(iter.next(), Some(3));
1235        assert_eq!(iter.next(), Some(2));
1236        assert_eq!(iter.next(), None);
1237        assert_eq!(iter.next(), None);
1238        assert_eq!(iter.next_back(), None);
1239        assert_eq!(iter.next_back(), None);
1240    }
1241
1242    #[test]
1243    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1244    fn test_vec_iter_panic_on_conversion() {
1245        let env = Env::default();
1246
1247        let vec: Val = (1i32,).try_into_val(&env).unwrap();
1248        let vec: Vec<i64> = vec.try_into_val(&env).unwrap();
1249
1250        let mut iter = vec.iter();
1251        iter.next();
1252    }
1253
1254    #[test]
1255    fn test_vec_try_iter() {
1256        let env = Env::default();
1257
1258        let vec: Vec<()> = vec![&env];
1259        let mut iter = vec.try_iter();
1260        assert_eq!(iter.len(), 0);
1261        assert_eq!(iter.next(), None);
1262        assert_eq!(iter.next(), None);
1263
1264        let vec = vec![&env, 0, 1, 2, 3, 4];
1265
1266        let mut iter = vec.try_iter();
1267        assert_eq!(iter.len(), 5);
1268        assert_eq!(iter.next(), Some(Ok(0)));
1269        assert_eq!(iter.len(), 4);
1270        assert_eq!(iter.next(), Some(Ok(1)));
1271        assert_eq!(iter.len(), 3);
1272        assert_eq!(iter.next(), Some(Ok(2)));
1273        assert_eq!(iter.len(), 2);
1274        assert_eq!(iter.next(), Some(Ok(3)));
1275        assert_eq!(iter.len(), 1);
1276        assert_eq!(iter.next(), Some(Ok(4)));
1277        assert_eq!(iter.len(), 0);
1278        assert_eq!(iter.next(), None);
1279        assert_eq!(iter.next(), None);
1280
1281        let mut iter = vec.try_iter();
1282        assert_eq!(iter.len(), 5);
1283        assert_eq!(iter.next(), Some(Ok(0)));
1284        assert_eq!(iter.len(), 4);
1285        assert_eq!(iter.next_back(), Some(Ok(4)));
1286        assert_eq!(iter.len(), 3);
1287        assert_eq!(iter.next_back(), Some(Ok(3)));
1288        assert_eq!(iter.len(), 2);
1289        assert_eq!(iter.next(), Some(Ok(1)));
1290        assert_eq!(iter.len(), 1);
1291        assert_eq!(iter.next(), Some(Ok(2)));
1292        assert_eq!(iter.len(), 0);
1293        assert_eq!(iter.next(), None);
1294        assert_eq!(iter.next(), None);
1295        assert_eq!(iter.next_back(), None);
1296        assert_eq!(iter.next_back(), None);
1297
1298        let mut iter = vec.try_iter().rev();
1299        assert_eq!(iter.next(), Some(Ok(4)));
1300        assert_eq!(iter.next_back(), Some(Ok(0)));
1301        assert_eq!(iter.next_back(), Some(Ok(1)));
1302        assert_eq!(iter.next(), Some(Ok(3)));
1303        assert_eq!(iter.next(), Some(Ok(2)));
1304        assert_eq!(iter.next(), None);
1305        assert_eq!(iter.next(), None);
1306        assert_eq!(iter.next_back(), None);
1307        assert_eq!(iter.next_back(), None);
1308    }
1309
1310    #[test]
1311    fn test_vec_try_iter_error_on_conversion() {
1312        let env = Env::default();
1313
1314        let vec: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1315        let vec: Vec<i64> = vec.try_into_val(&env).unwrap();
1316
1317        let mut iter = vec.try_iter();
1318        assert_eq!(iter.next(), Some(Ok(1)));
1319        assert_eq!(iter.next(), Some(Err(ConversionError.into())));
1320    }
1321
1322    #[test]
1323    fn test_vec_iter_into_vec() {
1324        let env = Env::default();
1325
1326        let vec = vec![&env, 0, 1, 2, 3, 4];
1327
1328        let mut iter = vec.try_iter();
1329        assert_eq!(iter.next(), Some(Ok(0)));
1330        assert_eq!(iter.next(), Some(Ok(1)));
1331        assert_eq!(iter.into_vec(), vec![&env, 2, 3, 4]);
1332    }
1333
1334    #[test]
1335    fn test_contains() {
1336        let env = Env::default();
1337        let vec = vec![&env, 0, 3, 5, 7, 9, 5];
1338        assert_eq!(vec.contains(&2), false);
1339        assert_eq!(vec.contains(2), false);
1340        assert_eq!(vec.contains(&3), true);
1341        assert_eq!(vec.contains(3), true);
1342        assert_eq!(vec.contains(&5), true);
1343        assert_eq!(vec.contains(5), true);
1344    }
1345
1346    #[test]
1347    fn test_first_index_of() {
1348        let env = Env::default();
1349
1350        let vec = vec![&env, 0, 3, 5, 7, 9, 5];
1351        assert_eq!(vec.first_index_of(&2), None);
1352        assert_eq!(vec.first_index_of(2), None);
1353        assert_eq!(vec.first_index_of(&3), Some(1));
1354        assert_eq!(vec.first_index_of(3), Some(1));
1355        assert_eq!(vec.first_index_of(&5), Some(2));
1356        assert_eq!(vec.first_index_of(5), Some(2));
1357    }
1358
1359    #[test]
1360    fn test_last_index_of() {
1361        let env = Env::default();
1362
1363        let vec = vec![&env, 0, 3, 5, 7, 9, 5];
1364        assert_eq!(vec.last_index_of(&2), None);
1365        assert_eq!(vec.last_index_of(2), None);
1366        assert_eq!(vec.last_index_of(&3), Some(1));
1367        assert_eq!(vec.last_index_of(3), Some(1));
1368        assert_eq!(vec.last_index_of(&5), Some(5));
1369        assert_eq!(vec.last_index_of(5), Some(5));
1370    }
1371
1372    #[test]
1373    fn test_binary_search() {
1374        let env = Env::default();
1375
1376        let vec = vec![&env, 0, 3, 5, 5, 7, 9];
1377        assert_eq!(vec.binary_search(&2), Err(1));
1378        assert_eq!(vec.binary_search(2), Err(1));
1379        assert_eq!(vec.binary_search(&3), Ok(1));
1380        assert_eq!(vec.binary_search(3), Ok(1));
1381        assert_eq!(vec.binary_search(&5), Ok(3));
1382        assert_eq!(vec.binary_search(5), Ok(3));
1383    }
1384
1385    #[cfg(not(target_family = "wasm"))]
1386    #[test]
1387    fn test_scval_accessibility_from_udt_types() {
1388        use crate::TryFromVal;
1389        let env = Env::default();
1390        let v = vec![&env, 1];
1391        let val: ScVal = v.clone().try_into().unwrap();
1392        let roundtrip = Vec::<i64>::try_from_val(&env, &val).unwrap();
1393        assert_eq!(v, roundtrip);
1394    }
1395
1396    #[test]
1397    fn test_insert_and_set() {
1398        let env = Env::default();
1399        let mut v = Vec::<i64>::new(&env);
1400        v.insert(0, 3);
1401        v.insert(0, 1);
1402        v.insert(1, 4);
1403        v.insert(3, 6);
1404        assert_eq!(v, vec![&env, 1, 4, 3, 6]);
1405        v.set(0, 7);
1406        v.set(1, 6);
1407        v.set(2, 2);
1408        v.set(3, 5);
1409        assert_eq!(v, vec![&env, 7, 6, 2, 5]);
1410    }
1411
1412    #[test]
1413    fn test_is_empty_and_len() {
1414        let env = Env::default();
1415
1416        let mut v: Vec<i32> = vec![&env, 1, 4, 3];
1417        assert_eq!(v.is_empty(), false);
1418        assert_eq!(v.len(), 3);
1419
1420        v = vec![&env];
1421        assert_eq!(v.is_empty(), true);
1422        assert_eq!(v.len(), 0);
1423    }
1424
1425    #[test]
1426    fn test_push_pop_front() {
1427        let env = Env::default();
1428
1429        let mut v = Vec::<i64>::new(&env);
1430        v.push_front(42);
1431        assert_eq!(v, vec![&env, 42]);
1432        v.push_front(1);
1433        assert_eq!(v, vec![&env, 1, 42]);
1434        v.push_front(5);
1435        assert_eq!(v, vec![&env, 5, 1, 42]);
1436        v.push_front(7);
1437        assert_eq!(v, vec![&env, 7, 5, 1, 42]);
1438
1439        let popped = v.pop_front();
1440        assert_eq!(popped, Some(7));
1441        assert_eq!(v, vec![&env, 5, 1, 42]);
1442
1443        let popped = v.try_pop_front();
1444        assert_eq!(popped, Ok(Some(5)));
1445        assert_eq!(v, vec![&env, 1, 42]);
1446
1447        let popped = v.pop_front_unchecked();
1448        assert_eq!(popped, 1);
1449        assert_eq!(v, vec![&env, 42]);
1450
1451        let popped = v.try_pop_front_unchecked();
1452        assert_eq!(popped, Ok(42));
1453        assert_eq!(v, vec![&env]);
1454
1455        assert_eq!(v.pop_front(), None);
1456    }
1457
1458    #[test]
1459    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1460    fn test_pop_front_panics_on_conversion() {
1461        let env = Env::default();
1462
1463        let v: Val = (1i32,).try_into_val(&env).unwrap();
1464        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1465
1466        v.pop_front();
1467    }
1468
1469    #[test]
1470    fn test_try_pop_front_errors_on_conversion() {
1471        let env = Env::default();
1472
1473        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1474        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1475
1476        assert_eq!(v.try_pop_front(), Ok(Some(1)));
1477        assert_eq!(v.try_pop_front(), Err(ConversionError.into()));
1478    }
1479
1480    #[test]
1481    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1482    fn test_pop_front_unchecked_panics_on_conversion() {
1483        let env = Env::default();
1484
1485        let v: Val = (1i32,).try_into_val(&env).unwrap();
1486        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1487
1488        v.pop_front_unchecked();
1489    }
1490
1491    #[test]
1492    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1493    fn test_pop_front_unchecked_panics_on_out_of_bounds() {
1494        let env = Env::default();
1495
1496        let mut v = Vec::<i64>::new(&env);
1497
1498        v.pop_front_unchecked();
1499    }
1500
1501    #[test]
1502    fn test_try_pop_front_unchecked_errors_on_conversion() {
1503        let env = Env::default();
1504
1505        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1506        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1507
1508        assert_eq!(v.try_pop_front_unchecked(), Ok(1));
1509        assert_eq!(v.try_pop_front_unchecked(), Err(ConversionError.into()));
1510    }
1511
1512    #[test]
1513    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1514    fn test_try_pop_front_unchecked_panics_on_out_of_bounds() {
1515        let env = Env::default();
1516
1517        let mut v = Vec::<i64>::new(&env);
1518
1519        let _ = v.try_pop_front_unchecked();
1520    }
1521
1522    #[test]
1523    fn test_push_pop_back() {
1524        let env = Env::default();
1525
1526        let mut v = Vec::<i64>::new(&env);
1527        v.push_back(42);
1528        assert_eq!(v, vec![&env, 42]);
1529        v.push_back(1);
1530        assert_eq!(v, vec![&env, 42, 1]);
1531        v.push_back(5);
1532        assert_eq!(v, vec![&env, 42, 1, 5]);
1533        v.push_back(7);
1534        assert_eq!(v, vec![&env, 42, 1, 5, 7]);
1535
1536        let popped = v.pop_back();
1537        assert_eq!(popped, Some(7));
1538        assert_eq!(v, vec![&env, 42, 1, 5]);
1539
1540        let popped = v.try_pop_back();
1541        assert_eq!(popped, Ok(Some(5)));
1542        assert_eq!(v, vec![&env, 42, 1]);
1543
1544        let popped = v.pop_back_unchecked();
1545        assert_eq!(popped, 1);
1546        assert_eq!(v, vec![&env, 42]);
1547
1548        let popped = v.try_pop_back_unchecked();
1549        assert_eq!(popped, Ok(42));
1550        assert_eq!(v, vec![&env]);
1551
1552        assert_eq!(v.pop_back(), None);
1553    }
1554
1555    #[test]
1556    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1557    fn test_pop_back_panics_on_conversion() {
1558        let env = Env::default();
1559
1560        let v: Val = (1i32,).try_into_val(&env).unwrap();
1561        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1562
1563        v.pop_back();
1564    }
1565
1566    #[test]
1567    fn test_try_pop_back_errors_on_conversion() {
1568        let env = Env::default();
1569
1570        let v: Val = (1i32, 2i64).try_into_val(&env).unwrap();
1571        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1572
1573        assert_eq!(v.try_pop_back(), Ok(Some(2)));
1574        assert_eq!(v.try_pop_back(), Err(ConversionError.into()));
1575    }
1576
1577    #[test]
1578    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1579    fn test_pop_back_unchecked_panics_on_conversion() {
1580        let env = Env::default();
1581
1582        let v: Val = (1i32,).try_into_val(&env).unwrap();
1583        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1584
1585        v.pop_back_unchecked();
1586    }
1587
1588    #[test]
1589    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1590    fn test_pop_back_unchecked_panics_on_out_of_bounds() {
1591        let env = Env::default();
1592
1593        let mut v = Vec::<i64>::new(&env);
1594
1595        v.pop_back_unchecked();
1596    }
1597
1598    #[test]
1599    fn test_try_pop_back_unchecked_errors_on_conversion() {
1600        let env = Env::default();
1601
1602        let v: Val = (1i32, 2i64).try_into_val(&env).unwrap();
1603        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1604
1605        assert_eq!(v.try_pop_back_unchecked(), Ok(2));
1606        assert_eq!(v.try_pop_back_unchecked(), Err(ConversionError.into()));
1607    }
1608
1609    #[test]
1610    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1611    fn test_try_pop_back_unchecked_panics_on_out_of_bounds() {
1612        let env = Env::default();
1613
1614        let mut v = Vec::<i64>::new(&env);
1615
1616        let _ = v.try_pop_back_unchecked();
1617    }
1618
1619    #[test]
1620    fn test_get() {
1621        let env = Env::default();
1622
1623        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1624
1625        // get each item
1626        assert_eq!(v.get(3), Some(5));
1627        assert_eq!(v.get(0), Some(0));
1628        assert_eq!(v.get(1), Some(3));
1629        assert_eq!(v.get(2), Some(5));
1630        assert_eq!(v.get(5), Some(9));
1631        assert_eq!(v.get(4), Some(7));
1632
1633        assert_eq!(v.get(v.len()), None);
1634        assert_eq!(v.get(v.len() + 1), None);
1635        assert_eq!(v.get(u32::MAX), None);
1636
1637        // tests on an empty vec
1638        let v = Vec::<i64>::new(&env);
1639        assert_eq!(v.get(0), None);
1640        assert_eq!(v.get(v.len()), None);
1641        assert_eq!(v.get(v.len() + 1), None);
1642        assert_eq!(v.get(u32::MAX), None);
1643    }
1644
1645    #[test]
1646    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1647    fn test_get_panics_on_conversion() {
1648        let env = Env::default();
1649
1650        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1651        let v: Vec<i64> = v.try_into_val(&env).unwrap();
1652
1653        // panic because element one is not of the expected type
1654        assert_eq!(v.get(1), Some(5));
1655    }
1656
1657    #[test]
1658    fn test_try_get() {
1659        let env = Env::default();
1660
1661        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1662
1663        // get each item
1664        assert_eq!(v.try_get(3), Ok(Some(5)));
1665        assert_eq!(v.try_get(0), Ok(Some(0)));
1666        assert_eq!(v.try_get(1), Ok(Some(3)));
1667        assert_eq!(v.try_get(2), Ok(Some(5)));
1668        assert_eq!(v.try_get(5), Ok(Some(9)));
1669        assert_eq!(v.try_get(4), Ok(Some(7)));
1670
1671        assert_eq!(v.try_get(v.len()), Ok(None));
1672        assert_eq!(v.try_get(v.len() + 1), Ok(None));
1673        assert_eq!(v.try_get(u32::MAX), Ok(None));
1674
1675        // tests on an empty vec
1676        let v = Vec::<i64>::new(&env);
1677        assert_eq!(v.try_get(0), Ok(None));
1678        assert_eq!(v.try_get(v.len()), Ok(None));
1679        assert_eq!(v.try_get(v.len() + 1), Ok(None));
1680        assert_eq!(v.try_get(u32::MAX), Ok(None));
1681
1682        // errors
1683        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1684        let v: Vec<i64> = v.try_into_val(&env).unwrap();
1685        assert_eq!(v.try_get(0), Ok(Some(1)));
1686        assert_eq!(v.try_get(1), Err(ConversionError.into()));
1687    }
1688
1689    #[test]
1690    fn test_get_unchecked() {
1691        let env = Env::default();
1692
1693        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1694
1695        // get each item
1696        assert_eq!(v.get_unchecked(3), 5);
1697        assert_eq!(v.get_unchecked(0), 0);
1698        assert_eq!(v.get_unchecked(1), 3);
1699        assert_eq!(v.get_unchecked(2), 5);
1700        assert_eq!(v.get_unchecked(5), 9);
1701        assert_eq!(v.get_unchecked(4), 7);
1702    }
1703
1704    #[test]
1705    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1706    fn test_get_unchecked_panics_on_conversion() {
1707        let env = Env::default();
1708
1709        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1710        let v: Vec<i64> = v.try_into_val(&env).unwrap();
1711
1712        // panic because element one is not of the expected type
1713        v.get_unchecked(1);
1714    }
1715
1716    #[test]
1717    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1718    fn test_get_unchecked_panics_on_out_of_bounds() {
1719        let env = Env::default();
1720
1721        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1722        _ = v.get_unchecked(v.len()); // out of bound get
1723    }
1724
1725    #[test]
1726    fn test_try_get_unchecked() {
1727        let env = Env::default();
1728
1729        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1730
1731        // get each item
1732        assert_eq!(v.try_get_unchecked(3), Ok(5));
1733        assert_eq!(v.try_get_unchecked(0), Ok(0));
1734        assert_eq!(v.try_get_unchecked(1), Ok(3));
1735        assert_eq!(v.try_get_unchecked(2), Ok(5));
1736        assert_eq!(v.try_get_unchecked(5), Ok(9));
1737        assert_eq!(v.try_get_unchecked(4), Ok(7));
1738
1739        // errors
1740        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1741        let v: Vec<i64> = v.try_into_val(&env).unwrap();
1742        assert_eq!(v.try_get_unchecked(0), Ok(1));
1743        assert_eq!(v.try_get_unchecked(1), Err(ConversionError.into()));
1744    }
1745
1746    #[test]
1747    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1748    fn test_try_get_unchecked_panics() {
1749        let env = Env::default();
1750
1751        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1752        _ = v.try_get_unchecked(v.len()); // out of bound get
1753    }
1754
1755    #[test]
1756    fn test_remove() {
1757        let env = Env::default();
1758        let mut v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1759
1760        assert_eq!(v.remove(0), Some(()));
1761        assert_eq!(v.remove(2), Some(()));
1762        assert_eq!(v.remove(3), Some(()));
1763
1764        assert_eq!(v, vec![&env, 3, 5, 7]);
1765        assert_eq!(v.len(), 3);
1766
1767        // out of bound removes
1768        assert_eq!(v.remove(v.len()), None);
1769        assert_eq!(v.remove(v.len() + 1), None);
1770        assert_eq!(v.remove(u32::MAX), None);
1771
1772        // remove rest of items
1773        assert_eq!(v.remove(0), Some(()));
1774        assert_eq!(v.remove(0), Some(()));
1775        assert_eq!(v.remove(0), Some(()));
1776        assert_eq!(v, vec![&env]);
1777        assert_eq!(v.len(), 0);
1778
1779        // try remove from empty vec
1780        assert_eq!(v.remove(0), None);
1781        assert_eq!(v.remove(v.len()), None);
1782        assert_eq!(v.remove(v.len() + 1), None);
1783        assert_eq!(v.remove(u32::MAX), None);
1784    }
1785
1786    #[test]
1787    fn test_remove_unchecked() {
1788        let env = Env::default();
1789        let mut v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1790
1791        assert_eq!(v.remove_unchecked(0), ());
1792        assert_eq!(v.remove_unchecked(2), ());
1793        assert_eq!(v.remove_unchecked(3), ());
1794
1795        assert_eq!(v, vec![&env, 3, 5, 7]);
1796        assert_eq!(v.len(), 3);
1797
1798        // remove rest of items
1799        assert_eq!(v.remove_unchecked(0), ());
1800        assert_eq!(v.remove_unchecked(0), ());
1801        assert_eq!(v.remove_unchecked(0), ());
1802        assert_eq!(v, vec![&env]);
1803        assert_eq!(v.len(), 0);
1804    }
1805
1806    #[test]
1807    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1808    fn test_remove_unchecked_panics() {
1809        let env = Env::default();
1810        let mut v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1811        v.remove_unchecked(v.len())
1812    }
1813}