Skip to main content

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> TryFromVal<Env, &Vec<T>> for Val {
214    type Error = ConversionError;
215
216    fn try_from_val(_env: &Env, v: &&Vec<T>) -> Result<Self, Self::Error> {
217        Ok(v.to_val())
218    }
219}
220
221impl<T> From<Vec<T>> for Val
222where
223    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
224{
225    #[inline(always)]
226    fn from(v: Vec<T>) -> Self {
227        v.obj.into()
228    }
229}
230
231impl<T> From<Vec<T>> for VecObject
232where
233    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
234{
235    #[inline(always)]
236    fn from(v: Vec<T>) -> Self {
237        v.obj
238    }
239}
240
241#[cfg(not(target_family = "wasm"))]
242use super::xdr::{ScVal, ScVec, VecM};
243
244#[cfg(not(target_family = "wasm"))]
245impl<T> From<&Vec<T>> for ScVal {
246    fn from(v: &Vec<T>) -> Self {
247        // This conversion occurs only in test utilities, and theoretically all
248        // values should convert to an ScVal because the Env won't let the host
249        // type to exist otherwise, unwrapping. Even if there are edge cases
250        // that don't, this is a trade off for a better test developer
251        // experience.
252        ScVal::try_from_val(&v.env, &v.obj.to_val()).unwrap()
253    }
254}
255
256#[cfg(not(target_family = "wasm"))]
257impl<T> From<&Vec<T>> for ScVec {
258    fn from(v: &Vec<T>) -> Self {
259        if let ScVal::Vec(Some(vec)) = ScVal::try_from(v).unwrap() {
260            vec
261        } else {
262            panic!("expected ScVec")
263        }
264    }
265}
266
267#[cfg(not(target_family = "wasm"))]
268impl<T> From<Vec<T>> for VecM<ScVal> {
269    fn from(v: Vec<T>) -> Self {
270        ScVec::from(v).0
271    }
272}
273
274#[cfg(not(target_family = "wasm"))]
275impl<T> From<Vec<T>> for ScVal {
276    fn from(v: Vec<T>) -> Self {
277        (&v).into()
278    }
279}
280
281#[cfg(not(target_family = "wasm"))]
282impl<T> From<Vec<T>> for ScVec {
283    fn from(v: Vec<T>) -> Self {
284        (&v).into()
285    }
286}
287
288#[cfg(not(target_family = "wasm"))]
289impl<T> TryFromVal<Env, ScVal> for Vec<T>
290where
291    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
292{
293    type Error = ConversionError;
294    fn try_from_val(env: &Env, val: &ScVal) -> Result<Self, ConversionError> {
295        Ok(VecObject::try_from_val(env, &Val::try_from_val(env, val)?)?
296            .try_into_val(env)
297            .unwrap_infallible())
298    }
299}
300
301#[cfg(not(target_family = "wasm"))]
302impl<T> TryFromVal<Env, ScVec> for Vec<T>
303where
304    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
305{
306    type Error = ConversionError;
307    fn try_from_val(env: &Env, val: &ScVec) -> Result<Self, Self::Error> {
308        ScVal::Vec(Some(val.clone())).try_into_val(env)
309    }
310}
311
312#[cfg(not(target_family = "wasm"))]
313impl<T> TryFromVal<Env, VecM<ScVal>> for Vec<T>
314where
315    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
316{
317    type Error = ConversionError;
318    fn try_from_val(env: &Env, val: &VecM<ScVal>) -> Result<Self, Self::Error> {
319        ScVec(val.clone()).try_into_val(env)
320    }
321}
322
323impl<T> Vec<T> {
324    #[inline(always)]
325    pub(crate) unsafe fn unchecked_new(env: Env, obj: VecObject) -> Self {
326        Self {
327            env,
328            obj,
329            _t: PhantomData,
330        }
331    }
332
333    pub fn env(&self) -> &Env {
334        &self.env
335    }
336
337    pub fn as_val(&self) -> &Val {
338        self.obj.as_val()
339    }
340
341    pub fn to_val(&self) -> Val {
342        self.obj.to_val()
343    }
344
345    pub fn as_object(&self) -> &VecObject {
346        &self.obj
347    }
348
349    pub fn to_object(&self) -> VecObject {
350        self.obj
351    }
352
353    pub fn to_vals(&self) -> Vec<Val> {
354        unsafe { Vec::<Val>::unchecked_new(self.env().clone(), self.obj) }
355    }
356}
357
358impl<T> Vec<T>
359where
360    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
361{
362    /// Create an empty Vec.
363    #[inline(always)]
364    pub fn new(env: &Env) -> Vec<T> {
365        unsafe { Self::unchecked_new(env.clone(), env.vec_new().unwrap_infallible()) }
366    }
367
368    /// Create a Vec from the array of items.
369    #[inline(always)]
370    pub fn from_array<const N: usize>(env: &Env, items: [T; N]) -> Vec<T> {
371        let mut tmp: [Val; N] = [Val::VOID.to_val(); N];
372        for (dst, src) in tmp.iter_mut().zip(items.iter()) {
373            *dst = src.into_val(env)
374        }
375        let vec = env.vec_new_from_slice(&tmp).unwrap_infallible();
376        unsafe { Self::unchecked_new(env.clone(), vec) }
377    }
378
379    /// Create a Vec from an iterator of items.
380    ///
381    /// This provides FromIterator-like functionality but requires an Env parameter.
382    ///
383    /// Note: This function iteratively adds each item one at a time, making a call to the Soroban
384    /// environment for each item making it inefficient for joining two [`Vec`]s. Use
385    /// [`Vec::append`] to join two [`Vec`]s.
386    ///
387    /// ### Examples
388    ///
389    /// ```
390    /// use soroban_sdk::{Env, Vec};
391    ///
392    /// let env = Env::default();
393    /// let items = vec![1, 2, 3, 4];
394    /// let vec = Vec::from_iter(&env, items.into_iter());
395    /// assert_eq!(vec.len(), 4);
396    /// ```
397    #[inline(always)]
398    pub fn from_iter<I: IntoIterator<Item = T>>(env: &Env, iter: I) -> Vec<T> {
399        let mut vec = Self::new(env);
400        vec.extend(iter);
401        vec
402    }
403
404    /// Create a Vec from the slice of items.
405    #[inline(always)]
406    pub fn from_slice(env: &Env, items: &[T]) -> Vec<T>
407    where
408        T: Clone,
409    {
410        let mut vec = Vec::new(env);
411        vec.extend_from_slice(items);
412        vec
413    }
414
415    /// Returns the item at the position or None if out-of-bounds.
416    ///
417    /// ### Panics
418    ///
419    /// If the value at the position cannot be converted to type T.
420    #[inline(always)]
421    pub fn get(&self, i: u32) -> Option<T> {
422        self.try_get(i).unwrap_optimized()
423    }
424
425    /// Returns the item at the position or None if out-of-bounds.
426    ///
427    /// ### Errors
428    ///
429    /// If the value at the position cannot be converted to type T.
430    #[inline(always)]
431    pub fn try_get(&self, i: u32) -> Result<Option<T>, T::Error> {
432        if i < self.len() {
433            self.try_get_unchecked(i).map(|val| Some(val))
434        } else {
435            Ok(None)
436        }
437    }
438
439    /// Returns the item at the position.
440    ///
441    /// ### Panics
442    ///
443    /// If the position is out-of-bounds.
444    ///
445    /// If the value at the position cannot be converted to type T.
446    #[inline(always)]
447    pub fn get_unchecked(&self, i: u32) -> T {
448        self.try_get_unchecked(i).unwrap_optimized()
449    }
450
451    /// Returns the item at the position.
452    ///
453    /// ### Errors
454    ///
455    /// If the value at the position cannot be converted to type T.
456    ///
457    /// ### Panics
458    ///
459    /// If the position is out-of-bounds.
460    #[inline(always)]
461    pub fn try_get_unchecked(&self, i: u32) -> Result<T, T::Error> {
462        let env = self.env();
463        let val = env.vec_get(self.obj, i.into()).unwrap_infallible();
464        T::try_from_val(env, &val)
465    }
466
467    /// Sets the item at the position with new value.
468    ///
469    /// ### Panics
470    ///
471    /// If the position is out-of-bounds.
472    #[inline(always)]
473    pub fn set(&mut self, i: u32, v: T) {
474        let env = self.env();
475        self.obj = env
476            .vec_put(self.obj, i.into(), v.into_val(env))
477            .unwrap_infallible();
478    }
479
480    /// Removes the item at the position.
481    ///
482    /// Returns `None` if out-of-bounds.
483    #[inline(always)]
484    pub fn remove(&mut self, i: u32) -> Option<()> {
485        if i < self.len() {
486            self.remove_unchecked(i);
487            Some(())
488        } else {
489            None
490        }
491    }
492
493    /// Removes the item at the position.
494    ///
495    /// ### Panics
496    ///
497    /// If the position is out-of-bounds.
498    #[inline(always)]
499    pub fn remove_unchecked(&mut self, i: u32) {
500        let env = self.env();
501        self.obj = env.vec_del(self.obj, i.into()).unwrap_infallible();
502    }
503
504    /// Adds the item to the front.
505    ///
506    /// Increases the length by one, shifts all items up by one, and puts the
507    /// item in the first position.
508    #[inline(always)]
509    pub fn push_front(&mut self, x: T) {
510        let env = self.env();
511        self.obj = env
512            .vec_push_front(self.obj, x.into_val(env))
513            .unwrap_infallible();
514    }
515
516    /// Removes and returns the first item or None if empty.
517    ///
518    /// ### Panics
519    ///
520    /// If the value at the first position cannot be converted to type T.
521    #[inline(always)]
522    pub fn pop_front(&mut self) -> Option<T> {
523        self.try_pop_front().unwrap_optimized()
524    }
525
526    /// Removes and returns the first item or None if empty.
527    ///
528    /// ### Errors
529    ///
530    /// If the value at the first position cannot be converted to type T.
531    #[inline(always)]
532    pub fn try_pop_front(&mut self) -> Result<Option<T>, T::Error> {
533        if self.is_empty() {
534            Ok(None)
535        } else {
536            self.try_pop_front_unchecked().map(|val| Some(val))
537        }
538    }
539
540    /// Removes and returns the first item.
541    ///
542    /// ### Panics
543    ///
544    /// If the vec is empty.
545    ///
546    /// If the value at the first position cannot be converted to type T.
547    #[inline(always)]
548    pub fn pop_front_unchecked(&mut self) -> T {
549        self.try_pop_front_unchecked().unwrap_optimized()
550    }
551
552    /// Removes and returns the first item.
553    ///
554    /// ### Errors
555    ///
556    /// If the value at the first position cannot be converted to type T.
557    ///
558    /// ### Panics
559    ///
560    /// If the vec is empty.
561    #[inline(always)]
562    pub fn try_pop_front_unchecked(&mut self) -> Result<T, T::Error> {
563        let last = self.try_first_unchecked()?;
564        let env = self.env();
565        self.obj = env.vec_pop_front(self.obj).unwrap_infallible();
566        Ok(last)
567    }
568
569    /// Adds the item to the back.
570    ///
571    /// Increases the length by one and puts the item in the last position.
572    #[inline(always)]
573    pub fn push_back(&mut self, x: T) {
574        let env = self.env();
575        self.obj = env
576            .vec_push_back(self.obj, x.into_val(env))
577            .unwrap_infallible();
578    }
579
580    /// Removes and returns the last item or None if empty.
581    ///
582    /// ### Panics
583    ///
584    /// If the value at the last position cannot be converted to type T.
585    #[inline(always)]
586    pub fn pop_back(&mut self) -> Option<T> {
587        self.try_pop_back().unwrap_optimized()
588    }
589
590    /// Removes and returns the last item or None if empty.
591    ///
592    /// ### Errors
593    ///
594    /// If the value at the last position cannot be converted to type T.
595    #[inline(always)]
596    pub fn try_pop_back(&mut self) -> Result<Option<T>, T::Error> {
597        if self.is_empty() {
598            Ok(None)
599        } else {
600            self.try_pop_back_unchecked().map(|val| Some(val))
601        }
602    }
603
604    /// Removes and returns the last item.
605    ///
606    /// ### Panics
607    ///
608    /// If the vec is empty.
609    ///
610    /// If the value at the last position cannot be converted to type T.
611    #[inline(always)]
612    pub fn pop_back_unchecked(&mut self) -> T {
613        self.try_pop_back_unchecked().unwrap_optimized()
614    }
615
616    /// Removes and returns the last item.
617    ///
618    /// ### Errors
619    ///
620    /// If the value at the last position cannot be converted to type T.
621    ///
622    /// ### Panics
623    ///
624    /// If the vec is empty.
625    #[inline(always)]
626    pub fn try_pop_back_unchecked(&mut self) -> Result<T, T::Error> {
627        let last = self.try_last_unchecked()?;
628        let env = self.env();
629        self.obj = env.vec_pop_back(self.obj).unwrap_infallible();
630        Ok(last)
631    }
632
633    /// Returns the first item or None if empty.
634    ///
635    /// ### Panics
636    ///
637    /// If the value at the first position cannot be converted to type T.
638    #[inline(always)]
639    pub fn first(&self) -> Option<T> {
640        self.try_first().unwrap_optimized()
641    }
642
643    /// Returns the first item or None if empty.
644    ///
645    /// ### Errors
646    ///
647    /// If the value at the first position cannot be converted to type T.
648    #[inline(always)]
649    pub fn try_first(&self) -> Result<Option<T>, T::Error> {
650        if self.is_empty() {
651            Ok(None)
652        } else {
653            self.try_first_unchecked().map(|val| Some(val))
654        }
655    }
656
657    /// Returns the first item.
658    ///
659    /// ### Panics
660    ///
661    /// If the vec is empty.
662    ///
663    /// If the value at the first position cannot be converted to type T.
664    #[inline(always)]
665    pub fn first_unchecked(&self) -> T {
666        self.try_first_unchecked().unwrap_optimized()
667    }
668
669    /// Returns the first item.
670    ///
671    /// ### Errors
672    ///
673    /// If the value at the first position cannot be converted to type T.
674    ///
675    /// ### Panics
676    ///
677    /// If the vec is empty.
678    #[inline(always)]
679    pub fn try_first_unchecked(&self) -> Result<T, T::Error> {
680        let env = &self.env;
681        let val = env.vec_front(self.obj).unwrap_infallible();
682        T::try_from_val(env, &val)
683    }
684
685    /// Returns the last item or None if empty.
686    ///
687    /// ### Panics
688    ///
689    /// If the value at the last position cannot be converted to type T.
690    #[inline(always)]
691    pub fn last(&self) -> Option<T> {
692        self.try_last().unwrap_optimized()
693    }
694
695    /// Returns the last item or None if empty.
696    ///
697    /// ### Errors
698    ///
699    /// If the value at the last position cannot be converted to type T.
700    #[inline(always)]
701    pub fn try_last(&self) -> Result<Option<T>, T::Error> {
702        if self.is_empty() {
703            Ok(None)
704        } else {
705            self.try_last_unchecked().map(|val| Some(val))
706        }
707    }
708
709    /// Returns the last item.
710    ///
711    /// ### Panics
712    ///
713    /// If the vec is empty.
714    ///
715    /// If the value at the last position cannot be converted to type T.
716    #[inline(always)]
717    pub fn last_unchecked(&self) -> T {
718        self.try_last_unchecked().unwrap_optimized()
719    }
720
721    /// Returns the last item.
722    ///
723    /// ### Errors
724    ///
725    /// If the value at the last position cannot be converted to type T.
726    ///
727    /// ### Panics
728    ///
729    /// If the vec is empty.
730    #[inline(always)]
731    pub fn try_last_unchecked(&self) -> Result<T, T::Error> {
732        let env = self.env();
733        let val = env.vec_back(self.obj).unwrap_infallible();
734        T::try_from_val(env, &val)
735    }
736
737    /// Inserts an item at the position.
738    ///
739    /// ### Panics
740    ///
741    /// If the position is out-of-bounds.
742    #[inline(always)]
743    pub fn insert(&mut self, i: u32, x: T) {
744        let env = self.env();
745        self.obj = env
746            .vec_insert(self.obj, i.into(), x.into_val(env))
747            .unwrap_infallible();
748    }
749
750    /// Append the items.
751    #[inline(always)]
752    pub fn append(&mut self, other: &Vec<T>) {
753        let env = self.env();
754        self.obj = env.vec_append(self.obj, other.obj).unwrap_infallible();
755    }
756
757    /// Extend with the items in the array.
758    #[inline(always)]
759    pub fn extend_from_array<const N: usize>(&mut self, items: [T; N]) {
760        self.append(&Self::from_array(&self.env, items))
761    }
762
763    /// Extend with the items in the slice.
764    #[inline(always)]
765    pub fn extend_from_slice(&mut self, items: &[T])
766    where
767        T: Clone,
768    {
769        for item in items {
770            self.push_back(item.clone());
771        }
772    }
773}
774
775impl<T> Vec<T> {
776    /// Returns a subset of the bytes as defined by the start and end bounds of
777    /// the range.
778    ///
779    /// ### Panics
780    ///
781    /// If the range is out-of-bounds.
782    #[must_use]
783    pub fn slice(&self, r: impl RangeBounds<u32>) -> Self {
784        let start_bound = match r.start_bound() {
785            Bound::Included(s) => *s,
786            Bound::Excluded(s) => s
787                .checked_add(1)
788                .expect_optimized("attempt to add with overflow"),
789            Bound::Unbounded => 0,
790        };
791        let end_bound = match r.end_bound() {
792            Bound::Included(s) => s
793                .checked_add(1)
794                .expect_optimized("attempt to add with overflow"),
795            Bound::Excluded(s) => *s,
796            Bound::Unbounded => self.len(),
797        };
798        let env = self.env();
799        let obj = env
800            .vec_slice(self.obj, start_bound.into(), end_bound.into())
801            .unwrap_infallible();
802        unsafe { Self::unchecked_new(env.clone(), obj) }
803    }
804
805    /// Returns copy of the vec shuffled using the NOT-SECURE PRNG.
806    ///
807    /// In tests, must be called from within a running contract.
808    ///
809    /// # Warning
810    ///
811    /// **The pseudo-random generator used to perform the shuffle is not
812    /// suitable for security-sensitive work.**
813    pub fn shuffle(&mut self) {
814        let env = self.env();
815        env.prng().shuffle(self);
816    }
817
818    /// Returns copy of the vec shuffled using the NOT-SECURE PRNG.
819    ///
820    /// In tests, must be called from within a running contract.
821    ///
822    /// # Warning
823    ///
824    /// **The pseudo-random generator used to perform the shuffle is not
825    /// suitable for security-sensitive work.**
826    #[must_use]
827    pub fn to_shuffled(&self) -> Self {
828        let mut copy = self.clone();
829        copy.shuffle();
830        copy
831    }
832
833    /// Returns true if the vec is empty and contains no items.
834    #[inline(always)]
835    pub fn is_empty(&self) -> bool {
836        self.len() == 0
837    }
838
839    /// Returns the number of items in the vec.
840    #[inline(always)]
841    pub fn len(&self) -> u32 {
842        self.env.vec_len(self.obj).unwrap_infallible().into()
843    }
844}
845
846impl<T> Vec<T>
847where
848    T: IntoVal<Env, Val>,
849{
850    /// Returns true if the Vec contains the item.
851    #[inline(always)]
852    pub fn contains(&self, item: impl Borrow<T>) -> bool {
853        let env = self.env();
854        let val = item.borrow().into_val(env);
855        !env.vec_first_index_of(self.obj, val)
856            .unwrap_infallible()
857            .is_void()
858    }
859
860    /// Returns the index of the first occurrence of the item.
861    ///
862    /// If the item cannot be found [None] is returned.
863    #[inline(always)]
864    pub fn first_index_of(&self, item: impl Borrow<T>) -> Option<u32> {
865        let env = self.env();
866        let val = item.borrow().into_val(env);
867        env.vec_first_index_of(self.obj, val)
868            .unwrap_infallible()
869            .try_into_val(env)
870            .unwrap()
871    }
872
873    /// Returns the index of the last occurrence of the item.
874    ///
875    /// If the item cannot be found [None] is returned.
876    #[inline(always)]
877    pub fn last_index_of(&self, item: impl Borrow<T>) -> Option<u32> {
878        let env = self.env();
879        let val = item.borrow().into_val(env);
880        env.vec_last_index_of(self.obj, val)
881            .unwrap_infallible()
882            .try_into_val(env)
883            .unwrap()
884    }
885
886    /// Returns the index of an occurrence of the item in an already sorted
887    /// [Vec], or the index of where the item can be inserted to keep the [Vec]
888    /// sorted.
889    ///
890    /// If the item is found, [Result::Ok] is returned containing the index of
891    /// the item.
892    ///
893    /// If the item is not found, [Result::Err] is returned containing the index
894    /// of where the item could be inserted to retain the sorted ordering.
895    #[inline(always)]
896    pub fn binary_search(&self, item: impl Borrow<T>) -> Result<u32, u32> {
897        let env = self.env();
898        let val = item.borrow().into_val(env);
899        let high_low = env.vec_binary_search(self.obj, val).unwrap_infallible();
900        let high: u32 = (high_low >> u32::BITS) as u32;
901        let low: u32 = high_low as u32;
902        if high == 1 {
903            Ok(low)
904        } else {
905            Err(low)
906        }
907    }
908}
909
910impl<T> Vec<Vec<T>>
911where
912    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
913    T: Clone,
914{
915    #[inline(always)]
916    pub fn concat(&self) -> Vec<T> {
917        let mut concatenated = vec![self.env()];
918        for vec in self.iter() {
919            concatenated.append(&vec);
920        }
921        concatenated
922    }
923}
924
925impl<T> IntoIterator for Vec<T>
926where
927    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
928{
929    type Item = T;
930    type IntoIter = UnwrappedIter<VecTryIter<T>, T, T::Error>;
931
932    fn into_iter(self) -> Self::IntoIter {
933        VecTryIter::new(self).unwrapped()
934    }
935}
936
937impl<T> IntoIterator for &Vec<T>
938where
939    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
940{
941    type Item = T;
942    type IntoIter = UnwrappedIter<VecTryIter<T>, T, T::Error>;
943
944    fn into_iter(self) -> Self::IntoIter {
945        self.clone().into_iter()
946    }
947}
948
949impl<T> Extend<T> for Vec<T>
950where
951    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
952{
953    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
954        for item in iter {
955            self.push_back(item);
956        }
957    }
958}
959
960impl<T> Vec<T>
961where
962    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
963{
964    #[inline(always)]
965    pub fn iter(&self) -> UnwrappedIter<VecTryIter<T>, T, T::Error>
966    where
967        T: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
968        T::Error: Debug,
969    {
970        self.try_iter().unwrapped()
971    }
972
973    #[inline(always)]
974    pub fn try_iter(&self) -> VecTryIter<T>
975    where
976        T: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
977    {
978        VecTryIter::new(self.clone())
979    }
980
981    #[inline(always)]
982    pub fn into_try_iter(self) -> VecTryIter<T>
983    where
984        T: IntoVal<Env, Val> + TryFromVal<Env, Val> + Clone,
985        T::Error: Debug,
986    {
987        VecTryIter::new(self.clone())
988    }
989}
990
991#[derive(Clone)]
992pub struct VecTryIter<T> {
993    vec: Vec<T>,
994    start: u32, // inclusive
995    end: u32,   // exclusive
996}
997
998impl<T> VecTryIter<T> {
999    fn new(vec: Vec<T>) -> Self {
1000        Self {
1001            start: 0,
1002            end: vec.len(),
1003            vec,
1004        }
1005    }
1006
1007    fn into_vec(self) -> Vec<T> {
1008        self.vec.slice(self.start..self.end)
1009    }
1010}
1011
1012impl<T> Iterator for VecTryIter<T>
1013where
1014    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
1015{
1016    type Item = Result<T, T::Error>;
1017
1018    fn next(&mut self) -> Option<Self::Item> {
1019        if self.start < self.end {
1020            let val = self.vec.try_get_unchecked(self.start);
1021            self.start += 1;
1022            Some(val)
1023        } else {
1024            None
1025        }
1026    }
1027
1028    fn size_hint(&self) -> (usize, Option<usize>) {
1029        let len = (self.end - self.start) as usize;
1030        (len, Some(len))
1031    }
1032
1033    // TODO: Implement other functions as optimizations since the iterator is
1034    // backed by an indexable collection.
1035}
1036
1037impl<T> DoubleEndedIterator for VecTryIter<T>
1038where
1039    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
1040{
1041    fn next_back(&mut self) -> Option<Self::Item> {
1042        if self.start < self.end {
1043            let val = self.vec.try_get_unchecked(self.end - 1);
1044            self.end -= 1;
1045            Some(val)
1046        } else {
1047            None
1048        }
1049    }
1050
1051    // TODO: Implement other functions as optimizations since the iterator is
1052    // backed by an indexable collection.
1053}
1054
1055impl<T> FusedIterator for VecTryIter<T> where T: IntoVal<Env, Val> + TryFromVal<Env, Val> {}
1056
1057impl<T> ExactSizeIterator for VecTryIter<T>
1058where
1059    T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
1060{
1061    fn len(&self) -> usize {
1062        (self.end - self.start) as usize
1063    }
1064}
1065
1066#[cfg(test)]
1067mod test {
1068    use super::*;
1069
1070    #[test]
1071    fn test_vec_macro() {
1072        let env = Env::default();
1073        assert_eq!(vec![&env], Vec::<i32>::new(&env));
1074        assert_eq!(vec![&env,], Vec::<i32>::new(&env));
1075        assert_eq!(vec![&env, 1], {
1076            let mut v = Vec::new(&env);
1077            v.push_back(1);
1078            v
1079        });
1080        assert_eq!(vec![&env, 1,], {
1081            let mut v = Vec::new(&env);
1082            v.push_back(1);
1083            v
1084        });
1085        assert_eq!(vec![&env, 3, 2, 1,], {
1086            let mut v = Vec::new(&env);
1087            v.push_back(3);
1088            v.push_back(2);
1089            v.push_back(1);
1090            v
1091        });
1092    }
1093
1094    #[test]
1095    fn test_vec_to_val() {
1096        let env = Env::default();
1097
1098        let vec = Vec::<u32>::from_slice(&env, &[0, 1, 2, 3]);
1099        let val: Val = vec.clone().into_val(&env);
1100        let rt: Vec<u32> = val.into_val(&env);
1101
1102        assert_eq!(vec, rt);
1103    }
1104
1105    #[test]
1106    fn test_ref_vec_to_val() {
1107        let env = Env::default();
1108
1109        let vec = Vec::<u32>::from_slice(&env, &[0, 1, 2, 3]);
1110        let val: Val = (&vec).into_val(&env);
1111        let rt: Vec<u32> = val.into_val(&env);
1112
1113        assert_eq!(vec, rt);
1114    }
1115
1116    #[test]
1117    fn test_double_ref_vec_to_val() {
1118        let env = Env::default();
1119
1120        let vec = Vec::<u32>::from_slice(&env, &[0, 1, 2, 3]);
1121        let val: Val = (&&vec).into_val(&env);
1122        let rt: Vec<u32> = val.into_val(&env);
1123
1124        assert_eq!(vec, rt);
1125    }
1126
1127    #[test]
1128    fn test_vec_raw_val_type() {
1129        let env = Env::default();
1130
1131        let mut vec = Vec::<u32>::new(&env);
1132        assert_eq!(vec.len(), 0);
1133        vec.push_back(10);
1134        assert_eq!(vec.len(), 1);
1135        vec.push_back(20);
1136        assert_eq!(vec.len(), 2);
1137        vec.push_back(30);
1138        assert_eq!(vec.len(), 3);
1139
1140        let vec_ref = &vec;
1141        assert_eq!(vec_ref.len(), 3);
1142
1143        let mut vec_copy = vec.clone();
1144        assert!(vec == vec_copy);
1145        assert_eq!(vec_copy.len(), 3);
1146        vec_copy.push_back(40);
1147        assert_eq!(vec_copy.len(), 4);
1148        assert!(vec != vec_copy);
1149
1150        assert_eq!(vec.len(), 3);
1151        assert_eq!(vec_ref.len(), 3);
1152
1153        _ = vec_copy.pop_back_unchecked();
1154        assert!(vec == vec_copy);
1155    }
1156
1157    #[test]
1158    fn test_vec_env_val_type() {
1159        let env = Env::default();
1160
1161        let mut vec = Vec::<i64>::new(&env);
1162        assert_eq!(vec.len(), 0);
1163        vec.push_back(-10);
1164        assert_eq!(vec.len(), 1);
1165        vec.push_back(20);
1166        assert_eq!(vec.len(), 2);
1167        vec.push_back(-30);
1168        assert_eq!(vec.len(), 3);
1169
1170        let vec_ref = &vec;
1171        assert_eq!(vec_ref.len(), 3);
1172
1173        let mut vec_copy = vec.clone();
1174        assert!(vec == vec_copy);
1175        assert_eq!(vec_copy.len(), 3);
1176        vec_copy.push_back(40);
1177        assert_eq!(vec_copy.len(), 4);
1178        assert!(vec != vec_copy);
1179
1180        assert_eq!(vec.len(), 3);
1181        assert_eq!(vec_ref.len(), 3);
1182
1183        _ = vec_copy.pop_back_unchecked();
1184        assert!(vec == vec_copy);
1185    }
1186
1187    #[test]
1188    fn test_vec_to_vals() {
1189        let env = Env::default();
1190        let vec = vec![&env, 0, 1, 2, 3, 4];
1191        let vals = vec.to_vals();
1192        assert_eq!(
1193            vals,
1194            vec![
1195                &env,
1196                Val::from_i32(0).to_val(),
1197                Val::from_i32(1).to_val(),
1198                Val::from_i32(2).to_val(),
1199                Val::from_i32(3).to_val(),
1200                Val::from_i32(4).to_val(),
1201            ]
1202        );
1203    }
1204
1205    #[test]
1206    fn test_vec_recursive() {
1207        let env = Env::default();
1208
1209        let mut vec_inner = Vec::<i64>::new(&env);
1210        vec_inner.push_back(-10);
1211        assert_eq!(vec_inner.len(), 1);
1212
1213        let mut vec_outer = Vec::<Vec<i64>>::new(&env);
1214        vec_outer.push_back(vec_inner);
1215        assert_eq!(vec_outer.len(), 1);
1216    }
1217
1218    #[test]
1219    fn test_vec_concat() {
1220        let env = Env::default();
1221        let vec_1: Vec<i64> = vec![&env, 1, 2, 3];
1222        let vec_2: Vec<i64> = vec![&env, 4, 5, 6];
1223        let vec = vec![&env, vec_1, vec_2].concat();
1224        assert_eq!(vec, vec![&env, 1, 2, 3, 4, 5, 6]);
1225    }
1226
1227    #[test]
1228    fn test_vec_slice() {
1229        let env = Env::default();
1230
1231        let vec = vec![&env, 0, 1, 2, 3, 4];
1232        assert_eq!(vec.len(), 5);
1233
1234        let slice = vec.slice(..);
1235        assert_eq!(slice, vec![&env, 0, 1, 2, 3, 4]);
1236
1237        let slice = vec.slice(0..5);
1238        assert_eq!(slice, vec![&env, 0, 1, 2, 3, 4]);
1239
1240        let slice = vec.slice(0..=4);
1241        assert_eq!(slice, vec![&env, 0, 1, 2, 3, 4]);
1242
1243        let slice = vec.slice(1..);
1244        assert_eq!(slice, vec![&env, 1, 2, 3, 4]);
1245
1246        let slice = vec.slice(..4);
1247        assert_eq!(slice, vec![&env, 0, 1, 2, 3]);
1248
1249        let slice = vec.slice(..=3);
1250        assert_eq!(slice, vec![&env, 0, 1, 2, 3]);
1251
1252        let slice = vec.slice(1..4);
1253        assert_eq!(slice, vec![&env, 1, 2, 3]);
1254
1255        let slice = vec.slice(1..=3);
1256        assert_eq!(slice, vec![&env, 1, 2, 3]);
1257
1258        // An exclusive start is technically possible due to the lack of
1259        // constraints in the RangeBounds trait, however this is unlikely to
1260        // happen since no syntax shorthand exists for it.
1261        let slice = vec.slice((Bound::Excluded(0), Bound::Included(3)));
1262        assert_eq!(slice, vec![&env, 1, 2, 3]);
1263        let slice = vec.slice((Bound::Excluded(0), Bound::Excluded(3)));
1264        assert_eq!(slice, vec![&env, 1, 2]);
1265    }
1266
1267    #[test]
1268    fn test_vec_iter() {
1269        let env = Env::default();
1270
1271        let vec: Vec<()> = vec![&env];
1272        let mut iter = vec.iter();
1273        assert_eq!(iter.len(), 0);
1274        assert_eq!(iter.next(), None);
1275        assert_eq!(iter.next(), None);
1276
1277        let vec = vec![&env, 0, 1, 2, 3, 4];
1278
1279        let mut iter = vec.iter();
1280        assert_eq!(iter.len(), 5);
1281        assert_eq!(iter.next(), Some(0));
1282        assert_eq!(iter.len(), 4);
1283        assert_eq!(iter.next(), Some(1));
1284        assert_eq!(iter.len(), 3);
1285        assert_eq!(iter.next(), Some(2));
1286        assert_eq!(iter.len(), 2);
1287        assert_eq!(iter.next(), Some(3));
1288        assert_eq!(iter.len(), 1);
1289        assert_eq!(iter.next(), Some(4));
1290        assert_eq!(iter.len(), 0);
1291        assert_eq!(iter.next(), None);
1292        assert_eq!(iter.next(), None);
1293
1294        let mut iter = vec.iter();
1295        assert_eq!(iter.len(), 5);
1296        assert_eq!(iter.next(), Some(0));
1297        assert_eq!(iter.len(), 4);
1298        assert_eq!(iter.next_back(), Some(4));
1299        assert_eq!(iter.len(), 3);
1300        assert_eq!(iter.next_back(), Some(3));
1301        assert_eq!(iter.len(), 2);
1302        assert_eq!(iter.next(), Some(1));
1303        assert_eq!(iter.len(), 1);
1304        assert_eq!(iter.next(), Some(2));
1305        assert_eq!(iter.len(), 0);
1306        assert_eq!(iter.next(), None);
1307        assert_eq!(iter.next(), None);
1308        assert_eq!(iter.next_back(), None);
1309        assert_eq!(iter.next_back(), None);
1310
1311        let mut iter = vec.iter().rev();
1312        assert_eq!(iter.next(), Some(4));
1313        assert_eq!(iter.next_back(), Some(0));
1314        assert_eq!(iter.next_back(), Some(1));
1315        assert_eq!(iter.next(), Some(3));
1316        assert_eq!(iter.next(), Some(2));
1317        assert_eq!(iter.next(), None);
1318        assert_eq!(iter.next(), None);
1319        assert_eq!(iter.next_back(), None);
1320        assert_eq!(iter.next_back(), None);
1321    }
1322
1323    #[test]
1324    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1325    fn test_vec_iter_panic_on_conversion() {
1326        let env = Env::default();
1327
1328        let vec: Val = (1i32,).try_into_val(&env).unwrap();
1329        let vec: Vec<i64> = vec.try_into_val(&env).unwrap();
1330
1331        let mut iter = vec.iter();
1332        iter.next();
1333    }
1334
1335    #[test]
1336    fn test_vec_try_iter() {
1337        let env = Env::default();
1338
1339        let vec: Vec<()> = vec![&env];
1340        let mut iter = vec.try_iter();
1341        assert_eq!(iter.len(), 0);
1342        assert_eq!(iter.next(), None);
1343        assert_eq!(iter.next(), None);
1344
1345        let vec = vec![&env, 0, 1, 2, 3, 4];
1346
1347        let mut iter = vec.try_iter();
1348        assert_eq!(iter.len(), 5);
1349        assert_eq!(iter.next(), Some(Ok(0)));
1350        assert_eq!(iter.len(), 4);
1351        assert_eq!(iter.next(), Some(Ok(1)));
1352        assert_eq!(iter.len(), 3);
1353        assert_eq!(iter.next(), Some(Ok(2)));
1354        assert_eq!(iter.len(), 2);
1355        assert_eq!(iter.next(), Some(Ok(3)));
1356        assert_eq!(iter.len(), 1);
1357        assert_eq!(iter.next(), Some(Ok(4)));
1358        assert_eq!(iter.len(), 0);
1359        assert_eq!(iter.next(), None);
1360        assert_eq!(iter.next(), None);
1361
1362        let mut iter = vec.try_iter();
1363        assert_eq!(iter.len(), 5);
1364        assert_eq!(iter.next(), Some(Ok(0)));
1365        assert_eq!(iter.len(), 4);
1366        assert_eq!(iter.next_back(), Some(Ok(4)));
1367        assert_eq!(iter.len(), 3);
1368        assert_eq!(iter.next_back(), Some(Ok(3)));
1369        assert_eq!(iter.len(), 2);
1370        assert_eq!(iter.next(), Some(Ok(1)));
1371        assert_eq!(iter.len(), 1);
1372        assert_eq!(iter.next(), Some(Ok(2)));
1373        assert_eq!(iter.len(), 0);
1374        assert_eq!(iter.next(), None);
1375        assert_eq!(iter.next(), None);
1376        assert_eq!(iter.next_back(), None);
1377        assert_eq!(iter.next_back(), None);
1378
1379        let mut iter = vec.try_iter().rev();
1380        assert_eq!(iter.next(), Some(Ok(4)));
1381        assert_eq!(iter.next_back(), Some(Ok(0)));
1382        assert_eq!(iter.next_back(), Some(Ok(1)));
1383        assert_eq!(iter.next(), Some(Ok(3)));
1384        assert_eq!(iter.next(), Some(Ok(2)));
1385        assert_eq!(iter.next(), None);
1386        assert_eq!(iter.next(), None);
1387        assert_eq!(iter.next_back(), None);
1388        assert_eq!(iter.next_back(), None);
1389    }
1390
1391    #[test]
1392    fn test_vec_try_iter_error_on_conversion() {
1393        let env = Env::default();
1394
1395        let vec: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1396        let vec: Vec<i64> = vec.try_into_val(&env).unwrap();
1397
1398        let mut iter = vec.try_iter();
1399        assert_eq!(iter.next(), Some(Ok(1)));
1400        assert_eq!(iter.next(), Some(Err(ConversionError.into())));
1401    }
1402
1403    #[test]
1404    fn test_vec_iter_into_vec() {
1405        let env = Env::default();
1406
1407        let vec = vec![&env, 0, 1, 2, 3, 4];
1408
1409        let mut iter = vec.try_iter();
1410        assert_eq!(iter.next(), Some(Ok(0)));
1411        assert_eq!(iter.next(), Some(Ok(1)));
1412        assert_eq!(iter.into_vec(), vec![&env, 2, 3, 4]);
1413    }
1414
1415    #[test]
1416    fn test_contains() {
1417        let env = Env::default();
1418        let vec = vec![&env, 0, 3, 5, 7, 9, 5];
1419        assert_eq!(vec.contains(&2), false);
1420        assert_eq!(vec.contains(2), false);
1421        assert_eq!(vec.contains(&3), true);
1422        assert_eq!(vec.contains(3), true);
1423        assert_eq!(vec.contains(&5), true);
1424        assert_eq!(vec.contains(5), true);
1425    }
1426
1427    #[test]
1428    fn test_first_index_of() {
1429        let env = Env::default();
1430
1431        let vec = vec![&env, 0, 3, 5, 7, 9, 5];
1432        assert_eq!(vec.first_index_of(&2), None);
1433        assert_eq!(vec.first_index_of(2), None);
1434        assert_eq!(vec.first_index_of(&3), Some(1));
1435        assert_eq!(vec.first_index_of(3), Some(1));
1436        assert_eq!(vec.first_index_of(&5), Some(2));
1437        assert_eq!(vec.first_index_of(5), Some(2));
1438    }
1439
1440    #[test]
1441    fn test_last_index_of() {
1442        let env = Env::default();
1443
1444        let vec = vec![&env, 0, 3, 5, 7, 9, 5];
1445        assert_eq!(vec.last_index_of(&2), None);
1446        assert_eq!(vec.last_index_of(2), None);
1447        assert_eq!(vec.last_index_of(&3), Some(1));
1448        assert_eq!(vec.last_index_of(3), Some(1));
1449        assert_eq!(vec.last_index_of(&5), Some(5));
1450        assert_eq!(vec.last_index_of(5), Some(5));
1451    }
1452
1453    #[test]
1454    fn test_binary_search() {
1455        let env = Env::default();
1456
1457        let vec = vec![&env, 0, 3, 5, 5, 7, 9];
1458        assert_eq!(vec.binary_search(&2), Err(1));
1459        assert_eq!(vec.binary_search(2), Err(1));
1460        assert_eq!(vec.binary_search(&3), Ok(1));
1461        assert_eq!(vec.binary_search(3), Ok(1));
1462        assert_eq!(vec.binary_search(&5), Ok(3));
1463        assert_eq!(vec.binary_search(5), Ok(3));
1464    }
1465
1466    #[cfg(not(target_family = "wasm"))]
1467    #[test]
1468    fn test_scval_accessibility_from_udt_types() {
1469        use crate::TryFromVal;
1470        let env = Env::default();
1471        let v = vec![&env, 1];
1472        let val: ScVal = v.clone().try_into().unwrap();
1473        let roundtrip = Vec::<i64>::try_from_val(&env, &val).unwrap();
1474        assert_eq!(v, roundtrip);
1475    }
1476
1477    #[test]
1478    fn test_insert_and_set() {
1479        let env = Env::default();
1480        let mut v = Vec::<i64>::new(&env);
1481        v.insert(0, 3);
1482        v.insert(0, 1);
1483        v.insert(1, 4);
1484        v.insert(3, 6);
1485        assert_eq!(v, vec![&env, 1, 4, 3, 6]);
1486        v.set(0, 7);
1487        v.set(1, 6);
1488        v.set(2, 2);
1489        v.set(3, 5);
1490        assert_eq!(v, vec![&env, 7, 6, 2, 5]);
1491    }
1492
1493    #[test]
1494    fn test_is_empty_and_len() {
1495        let env = Env::default();
1496
1497        let mut v: Vec<i32> = vec![&env, 1, 4, 3];
1498        assert_eq!(v.is_empty(), false);
1499        assert_eq!(v.len(), 3);
1500
1501        v = vec![&env];
1502        assert_eq!(v.is_empty(), true);
1503        assert_eq!(v.len(), 0);
1504    }
1505
1506    #[test]
1507    fn test_push_pop_front() {
1508        let env = Env::default();
1509
1510        let mut v = Vec::<i64>::new(&env);
1511        v.push_front(42);
1512        assert_eq!(v, vec![&env, 42]);
1513        v.push_front(1);
1514        assert_eq!(v, vec![&env, 1, 42]);
1515        v.push_front(5);
1516        assert_eq!(v, vec![&env, 5, 1, 42]);
1517        v.push_front(7);
1518        assert_eq!(v, vec![&env, 7, 5, 1, 42]);
1519
1520        let popped = v.pop_front();
1521        assert_eq!(popped, Some(7));
1522        assert_eq!(v, vec![&env, 5, 1, 42]);
1523
1524        let popped = v.try_pop_front();
1525        assert_eq!(popped, Ok(Some(5)));
1526        assert_eq!(v, vec![&env, 1, 42]);
1527
1528        let popped = v.pop_front_unchecked();
1529        assert_eq!(popped, 1);
1530        assert_eq!(v, vec![&env, 42]);
1531
1532        let popped = v.try_pop_front_unchecked();
1533        assert_eq!(popped, Ok(42));
1534        assert_eq!(v, vec![&env]);
1535
1536        assert_eq!(v.pop_front(), None);
1537    }
1538
1539    #[test]
1540    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1541    fn test_pop_front_panics_on_conversion() {
1542        let env = Env::default();
1543
1544        let v: Val = (1i32,).try_into_val(&env).unwrap();
1545        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1546
1547        v.pop_front();
1548    }
1549
1550    #[test]
1551    fn test_try_pop_front_errors_on_conversion() {
1552        let env = Env::default();
1553
1554        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1555        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1556
1557        assert_eq!(v.try_pop_front(), Ok(Some(1)));
1558        assert_eq!(v.try_pop_front(), Err(ConversionError.into()));
1559    }
1560
1561    #[test]
1562    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1563    fn test_pop_front_unchecked_panics_on_conversion() {
1564        let env = Env::default();
1565
1566        let v: Val = (1i32,).try_into_val(&env).unwrap();
1567        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1568
1569        v.pop_front_unchecked();
1570    }
1571
1572    #[test]
1573    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1574    fn test_pop_front_unchecked_panics_on_out_of_bounds() {
1575        let env = Env::default();
1576
1577        let mut v = Vec::<i64>::new(&env);
1578
1579        v.pop_front_unchecked();
1580    }
1581
1582    #[test]
1583    fn test_try_pop_front_unchecked_errors_on_conversion() {
1584        let env = Env::default();
1585
1586        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1587        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1588
1589        assert_eq!(v.try_pop_front_unchecked(), Ok(1));
1590        assert_eq!(v.try_pop_front_unchecked(), Err(ConversionError.into()));
1591    }
1592
1593    #[test]
1594    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1595    fn test_try_pop_front_unchecked_panics_on_out_of_bounds() {
1596        let env = Env::default();
1597
1598        let mut v = Vec::<i64>::new(&env);
1599
1600        let _ = v.try_pop_front_unchecked();
1601    }
1602
1603    #[test]
1604    fn test_push_pop_back() {
1605        let env = Env::default();
1606
1607        let mut v = Vec::<i64>::new(&env);
1608        v.push_back(42);
1609        assert_eq!(v, vec![&env, 42]);
1610        v.push_back(1);
1611        assert_eq!(v, vec![&env, 42, 1]);
1612        v.push_back(5);
1613        assert_eq!(v, vec![&env, 42, 1, 5]);
1614        v.push_back(7);
1615        assert_eq!(v, vec![&env, 42, 1, 5, 7]);
1616
1617        let popped = v.pop_back();
1618        assert_eq!(popped, Some(7));
1619        assert_eq!(v, vec![&env, 42, 1, 5]);
1620
1621        let popped = v.try_pop_back();
1622        assert_eq!(popped, Ok(Some(5)));
1623        assert_eq!(v, vec![&env, 42, 1]);
1624
1625        let popped = v.pop_back_unchecked();
1626        assert_eq!(popped, 1);
1627        assert_eq!(v, vec![&env, 42]);
1628
1629        let popped = v.try_pop_back_unchecked();
1630        assert_eq!(popped, Ok(42));
1631        assert_eq!(v, vec![&env]);
1632
1633        assert_eq!(v.pop_back(), None);
1634    }
1635
1636    #[test]
1637    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1638    fn test_pop_back_panics_on_conversion() {
1639        let env = Env::default();
1640
1641        let v: Val = (1i32,).try_into_val(&env).unwrap();
1642        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1643
1644        v.pop_back();
1645    }
1646
1647    #[test]
1648    fn test_try_pop_back_errors_on_conversion() {
1649        let env = Env::default();
1650
1651        let v: Val = (1i32, 2i64).try_into_val(&env).unwrap();
1652        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1653
1654        assert_eq!(v.try_pop_back(), Ok(Some(2)));
1655        assert_eq!(v.try_pop_back(), Err(ConversionError.into()));
1656    }
1657
1658    #[test]
1659    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1660    fn test_pop_back_unchecked_panics_on_conversion() {
1661        let env = Env::default();
1662
1663        let v: Val = (1i32,).try_into_val(&env).unwrap();
1664        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1665
1666        v.pop_back_unchecked();
1667    }
1668
1669    #[test]
1670    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1671    fn test_pop_back_unchecked_panics_on_out_of_bounds() {
1672        let env = Env::default();
1673
1674        let mut v = Vec::<i64>::new(&env);
1675
1676        v.pop_back_unchecked();
1677    }
1678
1679    #[test]
1680    fn test_try_pop_back_unchecked_errors_on_conversion() {
1681        let env = Env::default();
1682
1683        let v: Val = (1i32, 2i64).try_into_val(&env).unwrap();
1684        let mut v: Vec<i64> = v.try_into_val(&env).unwrap();
1685
1686        assert_eq!(v.try_pop_back_unchecked(), Ok(2));
1687        assert_eq!(v.try_pop_back_unchecked(), Err(ConversionError.into()));
1688    }
1689
1690    #[test]
1691    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1692    fn test_try_pop_back_unchecked_panics_on_out_of_bounds() {
1693        let env = Env::default();
1694
1695        let mut v = Vec::<i64>::new(&env);
1696
1697        let _ = v.try_pop_back_unchecked();
1698    }
1699
1700    #[test]
1701    fn test_get() {
1702        let env = Env::default();
1703
1704        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1705
1706        // get each item
1707        assert_eq!(v.get(3), Some(5));
1708        assert_eq!(v.get(0), Some(0));
1709        assert_eq!(v.get(1), Some(3));
1710        assert_eq!(v.get(2), Some(5));
1711        assert_eq!(v.get(5), Some(9));
1712        assert_eq!(v.get(4), Some(7));
1713
1714        assert_eq!(v.get(v.len()), None);
1715        assert_eq!(v.get(v.len() + 1), None);
1716        assert_eq!(v.get(u32::MAX), None);
1717
1718        // tests on an empty vec
1719        let v = Vec::<i64>::new(&env);
1720        assert_eq!(v.get(0), None);
1721        assert_eq!(v.get(v.len()), None);
1722        assert_eq!(v.get(v.len() + 1), None);
1723        assert_eq!(v.get(u32::MAX), None);
1724    }
1725
1726    #[test]
1727    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1728    fn test_get_panics_on_conversion() {
1729        let env = Env::default();
1730
1731        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1732        let v: Vec<i64> = v.try_into_val(&env).unwrap();
1733
1734        // panic because element one is not of the expected type
1735        assert_eq!(v.get(1), Some(5));
1736    }
1737
1738    #[test]
1739    fn test_try_get() {
1740        let env = Env::default();
1741
1742        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1743
1744        // get each item
1745        assert_eq!(v.try_get(3), Ok(Some(5)));
1746        assert_eq!(v.try_get(0), Ok(Some(0)));
1747        assert_eq!(v.try_get(1), Ok(Some(3)));
1748        assert_eq!(v.try_get(2), Ok(Some(5)));
1749        assert_eq!(v.try_get(5), Ok(Some(9)));
1750        assert_eq!(v.try_get(4), Ok(Some(7)));
1751
1752        assert_eq!(v.try_get(v.len()), Ok(None));
1753        assert_eq!(v.try_get(v.len() + 1), Ok(None));
1754        assert_eq!(v.try_get(u32::MAX), Ok(None));
1755
1756        // tests on an empty vec
1757        let v = Vec::<i64>::new(&env);
1758        assert_eq!(v.try_get(0), Ok(None));
1759        assert_eq!(v.try_get(v.len()), Ok(None));
1760        assert_eq!(v.try_get(v.len() + 1), Ok(None));
1761        assert_eq!(v.try_get(u32::MAX), Ok(None));
1762
1763        // errors
1764        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1765        let v: Vec<i64> = v.try_into_val(&env).unwrap();
1766        assert_eq!(v.try_get(0), Ok(Some(1)));
1767        assert_eq!(v.try_get(1), Err(ConversionError.into()));
1768    }
1769
1770    #[test]
1771    fn test_get_unchecked() {
1772        let env = Env::default();
1773
1774        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1775
1776        // get each item
1777        assert_eq!(v.get_unchecked(3), 5);
1778        assert_eq!(v.get_unchecked(0), 0);
1779        assert_eq!(v.get_unchecked(1), 3);
1780        assert_eq!(v.get_unchecked(2), 5);
1781        assert_eq!(v.get_unchecked(5), 9);
1782        assert_eq!(v.get_unchecked(4), 7);
1783    }
1784
1785    #[test]
1786    #[should_panic(expected = "Error(Value, UnexpectedType)")]
1787    fn test_get_unchecked_panics_on_conversion() {
1788        let env = Env::default();
1789
1790        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1791        let v: Vec<i64> = v.try_into_val(&env).unwrap();
1792
1793        // panic because element one is not of the expected type
1794        v.get_unchecked(1);
1795    }
1796
1797    #[test]
1798    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1799    fn test_get_unchecked_panics_on_out_of_bounds() {
1800        let env = Env::default();
1801
1802        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1803        _ = v.get_unchecked(v.len()); // out of bound get
1804    }
1805
1806    #[test]
1807    fn test_try_get_unchecked() {
1808        let env = Env::default();
1809
1810        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1811
1812        // get each item
1813        assert_eq!(v.try_get_unchecked(3), Ok(5));
1814        assert_eq!(v.try_get_unchecked(0), Ok(0));
1815        assert_eq!(v.try_get_unchecked(1), Ok(3));
1816        assert_eq!(v.try_get_unchecked(2), Ok(5));
1817        assert_eq!(v.try_get_unchecked(5), Ok(9));
1818        assert_eq!(v.try_get_unchecked(4), Ok(7));
1819
1820        // errors
1821        let v: Val = (1i64, 2i32).try_into_val(&env).unwrap();
1822        let v: Vec<i64> = v.try_into_val(&env).unwrap();
1823        assert_eq!(v.try_get_unchecked(0), Ok(1));
1824        assert_eq!(v.try_get_unchecked(1), Err(ConversionError.into()));
1825    }
1826
1827    #[test]
1828    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1829    fn test_try_get_unchecked_panics() {
1830        let env = Env::default();
1831
1832        let v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1833        _ = v.try_get_unchecked(v.len()); // out of bound get
1834    }
1835
1836    #[test]
1837    fn test_remove() {
1838        let env = Env::default();
1839        let mut v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1840
1841        assert_eq!(v.remove(0), Some(()));
1842        assert_eq!(v.remove(2), Some(()));
1843        assert_eq!(v.remove(3), Some(()));
1844
1845        assert_eq!(v, vec![&env, 3, 5, 7]);
1846        assert_eq!(v.len(), 3);
1847
1848        // out of bound removes
1849        assert_eq!(v.remove(v.len()), None);
1850        assert_eq!(v.remove(v.len() + 1), None);
1851        assert_eq!(v.remove(u32::MAX), None);
1852
1853        // remove rest of items
1854        assert_eq!(v.remove(0), Some(()));
1855        assert_eq!(v.remove(0), Some(()));
1856        assert_eq!(v.remove(0), Some(()));
1857        assert_eq!(v, vec![&env]);
1858        assert_eq!(v.len(), 0);
1859
1860        // try remove from empty vec
1861        assert_eq!(v.remove(0), None);
1862        assert_eq!(v.remove(v.len()), None);
1863        assert_eq!(v.remove(v.len() + 1), None);
1864        assert_eq!(v.remove(u32::MAX), None);
1865    }
1866
1867    #[test]
1868    fn test_remove_unchecked() {
1869        let env = Env::default();
1870        let mut v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1871
1872        assert_eq!(v.remove_unchecked(0), ());
1873        assert_eq!(v.remove_unchecked(2), ());
1874        assert_eq!(v.remove_unchecked(3), ());
1875
1876        assert_eq!(v, vec![&env, 3, 5, 7]);
1877        assert_eq!(v.len(), 3);
1878
1879        // remove rest of items
1880        assert_eq!(v.remove_unchecked(0), ());
1881        assert_eq!(v.remove_unchecked(0), ());
1882        assert_eq!(v.remove_unchecked(0), ());
1883        assert_eq!(v, vec![&env]);
1884        assert_eq!(v.len(), 0);
1885    }
1886
1887    #[test]
1888    #[should_panic(expected = "HostError: Error(Object, IndexBounds)")]
1889    fn test_remove_unchecked_panics() {
1890        let env = Env::default();
1891        let mut v: Vec<i64> = vec![&env, 0, 3, 5, 5, 7, 9];
1892        v.remove_unchecked(v.len())
1893    }
1894
1895    #[test]
1896    fn test_extend() {
1897        let env = Env::default();
1898        let mut v: Vec<i64> = vec![&env, 1, 2, 3];
1899
1900        // Extend with a std vector
1901        let items = std::vec![4, 5, 6];
1902        v.extend(items);
1903        assert_eq!(v, vec![&env, 1, 2, 3, 4, 5, 6]);
1904        assert_eq!(v.len(), 6);
1905
1906        // Extend with an array
1907        v.extend([7, 8, 9]);
1908        assert_eq!(v, vec![&env, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1909        assert_eq!(v.len(), 9);
1910
1911        // Extend with an empty iterator
1912        let empty: std::vec::Vec<i64> = std::vec::Vec::new();
1913        v.extend(empty);
1914        assert_eq!(v, vec![&env, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1915        assert_eq!(v.len(), 9);
1916    }
1917
1918    #[test]
1919    fn test_extend_empty_vec() {
1920        let env = Env::default();
1921        let mut v: Vec<i64> = vec![&env];
1922
1923        // Extend empty vec with items
1924        v.extend([1, 2, 3, 4, 5]);
1925        assert_eq!(v, vec![&env, 1, 2, 3, 4, 5]);
1926        assert_eq!(v.len(), 5);
1927    }
1928
1929    #[test]
1930    fn test_from_iter() {
1931        let env = Env::default();
1932
1933        // Create from std vector iterator
1934        let items = std::vec![1, 2, 3, 4, 5];
1935        let v = Vec::from_iter(&env, items);
1936        assert_eq!(v, vec![&env, 1, 2, 3, 4, 5]);
1937        assert_eq!(v.len(), 5);
1938
1939        // Create from array iterator
1940        let v2 = Vec::from_iter(&env, [10, 20, 30]);
1941        assert_eq!(v2, vec![&env, 10, 20, 30]);
1942        assert_eq!(v2.len(), 3);
1943
1944        // Create from range
1945        let v3 = Vec::from_iter(&env, 1..=4);
1946        assert_eq!(v3, vec![&env, 1, 2, 3, 4]);
1947        assert_eq!(v3.len(), 4);
1948    }
1949
1950    #[test]
1951    fn test_from_iter_empty() {
1952        let env = Env::default();
1953
1954        // Create from empty iterator
1955        let empty: std::vec::Vec<i64> = std::vec::Vec::new();
1956        let v = Vec::from_iter(&env, empty);
1957        assert_eq!(v, vec![&env]);
1958        assert_eq!(v.len(), 0);
1959
1960        // Create from empty range
1961        let v2 = Vec::from_iter(&env, 1..1);
1962        assert_eq!(v2, vec![&env]);
1963        assert_eq!(v2.len(), 0);
1964    }
1965
1966    #[test]
1967    fn test_from_iter_different_types() {
1968        let env = Env::default();
1969
1970        // Test with strings
1971        let strings = std::vec!["hello".to_string(), "world".to_string(), "test".to_string()];
1972        let v = Vec::from_iter(&env, strings);
1973        assert_eq!(
1974            v,
1975            vec![
1976                &env,
1977                "hello".to_string(),
1978                "world".to_string(),
1979                "test".to_string()
1980            ]
1981        );
1982        assert_eq!(v.len(), 3);
1983
1984        // Test with booleans
1985        let bools = [true, false, true, false];
1986        let v2 = Vec::from_iter(&env, bools.into_iter());
1987        assert_eq!(v2, vec![&env, true, false, true, false]);
1988        assert_eq!(v2.len(), 4);
1989    }
1990}