rune/runtime/
vec.rs

1use core::cmp;
2use core::cmp::Ordering;
3use core::fmt;
4use core::ops;
5use core::slice;
6use core::slice::SliceIndex;
7
8use crate as rune;
9use crate::alloc;
10use crate::alloc::fmt::TryWrite;
11use crate::alloc::prelude::*;
12use crate::runtime::slice::Iter;
13#[cfg(feature = "alloc")]
14use crate::runtime::Hasher;
15use crate::{Any, TypeHash};
16
17use super::EnvProtocolCaller;
18use super::{
19    Formatter, FromValue, ProtocolCaller, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo,
20    RangeToInclusive, RawAnyGuard, Ref, RuntimeError, ToValue, UnsafeToRef, Value, VmErrorKind,
21    VmResult,
22};
23
24/// Struct representing a dynamic vector.
25///
26/// # Examples
27///
28/// ```
29/// let mut vec = rune::runtime::Vec::new();
30/// assert!(vec.is_empty());
31///
32/// vec.push_value(42).into_result()?;
33/// vec.push_value(true).into_result()?;
34/// assert_eq!(2, vec.len());
35///
36/// assert_eq!(Some(42), vec.get_value(0).into_result()?);
37/// assert_eq!(Some(true), vec.get_value(1).into_result()?);
38/// assert_eq!(None::<bool>, vec.get_value(2).into_result()?);
39/// # Ok::<_, rune::support::Error>(())
40/// ```
41#[derive(Default, Any)]
42#[repr(transparent)]
43#[rune(item = ::std::vec)]
44pub struct Vec {
45    inner: alloc::Vec<Value>,
46}
47
48impl Vec {
49    /// Constructs a new, empty dynamic `Vec`.
50    ///
51    /// The vector will not allocate until elements are pushed onto it.
52    ///
53    /// # Examples
54    ///
55    /// ```
56    /// use rune::runtime::Vec;
57    ///
58    /// let mut vec = Vec::new();
59    /// ```
60    pub const fn new() -> Self {
61        Self {
62            inner: alloc::Vec::new(),
63        }
64    }
65
66    /// Sort the vector with the given comparison function.
67    pub fn sort_by<F>(&mut self, compare: F)
68    where
69        F: FnMut(&Value, &Value) -> cmp::Ordering,
70    {
71        self.inner.sort_by(compare)
72    }
73
74    /// Construct a new dynamic vector guaranteed to have at least the given
75    /// capacity.
76    pub fn with_capacity(cap: usize) -> alloc::Result<Self> {
77        Ok(Self {
78            inner: alloc::Vec::try_with_capacity(cap)?,
79        })
80    }
81
82    /// Convert into inner rune alloc vector.
83    pub fn into_inner(self) -> alloc::Vec<Value> {
84        self.inner
85    }
86
87    /// Returns `true` if the vector contains no elements.
88    ///
89    /// # Examples
90    ///
91    /// ```
92    /// use rune::runtime::{Value, Vec};
93    ///
94    /// let mut v = Vec::new();
95    /// assert!(v.is_empty());
96    ///
97    /// v.push(rune::to_value(1u32)?);
98    /// assert!(!v.is_empty());
99    /// # Ok::<_, rune::support::Error>(())
100    /// ```
101    pub fn is_empty(&self) -> bool {
102        self.inner.is_empty()
103    }
104
105    /// Returns the number of elements in the dynamic vector, also referred to
106    /// as its 'length'.
107    pub fn len(&self) -> usize {
108        self.inner.len()
109    }
110
111    /// Returns the number of elements in the dynamic vector, also referred to
112    /// as its 'length'.
113    pub fn capacity(&self) -> usize {
114        self.inner.capacity()
115    }
116
117    /// Set by index
118    pub fn set(&mut self, index: usize, value: Value) -> VmResult<()> {
119        let Some(v) = self.inner.get_mut(index) else {
120            return VmResult::err(VmErrorKind::OutOfRange {
121                index: index.into(),
122                length: self.len().into(),
123            });
124        };
125
126        *v = value;
127        VmResult::Ok(())
128    }
129
130    /// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
131    ///
132    /// If `new_len` is greater than `len`, the `Vec` is extended by the
133    /// difference, with each additional slot filled with `value`. If `new_len`
134    /// is less than `len`, the `Vec` is simply truncated.
135    pub fn resize(&mut self, new_len: usize, value: Value) -> VmResult<()> {
136        if value.is_inline() {
137            vm_try!(self.inner.try_resize(new_len, value));
138        } else {
139            let len = self.inner.len();
140
141            if new_len > len {
142                for _ in 0..new_len - len {
143                    let value = vm_try!(value.clone_with(&mut EnvProtocolCaller));
144                    vm_try!(self.inner.try_push(value));
145                }
146            } else {
147                self.inner.truncate(new_len);
148            }
149        }
150
151        VmResult::Ok(())
152    }
153
154    /// Appends an element to the back of a dynamic vector.
155    pub fn push(&mut self, value: Value) -> alloc::Result<()> {
156        self.inner.try_push(value)
157    }
158
159    /// Appends an element to the back of a dynamic vector, converting it as
160    /// necessary through the [`ToValue`] trait.
161    pub fn push_value<T>(&mut self, value: T) -> VmResult<()>
162    where
163        T: ToValue,
164    {
165        vm_try!(self.inner.try_push(vm_try!(value.to_value())));
166        VmResult::Ok(())
167    }
168
169    /// Get the value at the given index.
170    pub fn get<I>(&self, index: I) -> Option<&I::Output>
171    where
172        I: SliceIndex<[Value]>,
173    {
174        self.inner.get(index)
175    }
176
177    /// Get the given value at the given index.
178    pub fn get_value<T>(&self, index: usize) -> VmResult<Option<T>>
179    where
180        T: FromValue,
181    {
182        let value = match self.inner.get(index) {
183            Some(value) => value.clone(),
184            None => return VmResult::Ok(None),
185        };
186
187        VmResult::Ok(Some(vm_try!(T::from_value(value))))
188    }
189
190    /// Get the mutable value at the given index.
191    pub fn get_mut(&mut self, index: usize) -> Option<&mut Value> {
192        self.inner.get_mut(index)
193    }
194
195    /// Removes the last element from a dynamic vector and returns it, or
196    /// [`None`] if it is empty.
197    pub fn pop(&mut self) -> Option<Value> {
198        self.inner.pop()
199    }
200
201    /// Removes the element at the specified index from a dynamic vector.
202    pub fn remove(&mut self, index: usize) -> Value {
203        self.inner.remove(index)
204    }
205
206    /// Clears the vector, removing all values.
207    ///
208    /// Note that this method has no effect on the allocated capacity of the
209    /// vector.
210    pub fn clear(&mut self) {
211        self.inner.clear();
212    }
213
214    /// Inserts an element at position index within the vector, shifting all
215    /// elements after it to the right.
216    pub fn insert(&mut self, index: usize, value: Value) -> VmResult<()> {
217        vm_try!(self.inner.try_insert(index, value));
218        VmResult::Ok(())
219    }
220
221    /// Extend this vector with something that implements the into_iter
222    /// protocol.
223    pub fn extend(&mut self, value: Value) -> VmResult<()> {
224        let mut it = vm_try!(value.into_iter());
225
226        while let Some(value) = vm_try!(it.next()) {
227            vm_try!(self.push(value));
228        }
229
230        VmResult::Ok(())
231    }
232
233    /// Iterate over the vector.
234    ///
235    /// # Examples
236    ///
237    /// ```rune
238    /// let vec = [1, 2, 3, 4];
239    /// let it = vec.iter();
240    ///
241    /// assert_eq!(it.next(), Some(1));
242    /// assert_eq!(it.next_back(), Some(4));
243    /// ```
244    #[rune::function(keep, path = Self::iter)]
245    pub fn rune_iter(this: Ref<Self>) -> Iter {
246        Iter::new(Ref::map(this, |vec| &**vec))
247    }
248
249    /// Access the inner values as a slice.
250    pub(crate) fn as_slice(&self) -> &[Value] {
251        &self.inner
252    }
253
254    pub(crate) fn debug_fmt_with(
255        this: &[Value],
256        f: &mut Formatter,
257        caller: &mut dyn ProtocolCaller,
258    ) -> VmResult<()> {
259        let mut it = this.iter().peekable();
260        vm_try!(vm_write!(f, "["));
261
262        while let Some(value) = it.next() {
263            vm_try!(value.debug_fmt_with(f, caller));
264
265            if it.peek().is_some() {
266                vm_try!(vm_write!(f, ", "));
267            }
268        }
269
270        vm_try!(vm_write!(f, "]"));
271        VmResult::Ok(())
272    }
273
274    pub(crate) fn partial_eq_with(
275        a: &[Value],
276        b: Value,
277        caller: &mut dyn ProtocolCaller,
278    ) -> VmResult<bool> {
279        let mut b = vm_try!(b.into_iter_with(caller));
280
281        for a in a {
282            let Some(b) = vm_try!(b.next()) else {
283                return VmResult::Ok(false);
284            };
285
286            if !vm_try!(Value::partial_eq_with(a, &b, caller)) {
287                return VmResult::Ok(false);
288            }
289        }
290
291        if vm_try!(b.next()).is_some() {
292            return VmResult::Ok(false);
293        }
294
295        VmResult::Ok(true)
296    }
297
298    pub(crate) fn eq_with(
299        a: &[Value],
300        b: &[Value],
301        eq: fn(&Value, &Value, &mut dyn ProtocolCaller) -> VmResult<bool>,
302        caller: &mut dyn ProtocolCaller,
303    ) -> VmResult<bool> {
304        if a.len() != b.len() {
305            return VmResult::Ok(false);
306        }
307
308        for (a, b) in a.iter().zip(b.iter()) {
309            if !vm_try!(eq(a, b, caller)) {
310                return VmResult::Ok(false);
311            }
312        }
313
314        VmResult::Ok(true)
315    }
316
317    pub(crate) fn partial_cmp_with(
318        a: &[Value],
319        b: &[Value],
320        caller: &mut dyn ProtocolCaller,
321    ) -> VmResult<Option<Ordering>> {
322        let mut b = b.iter();
323
324        for a in a.iter() {
325            let Some(b) = b.next() else {
326                return VmResult::Ok(Some(Ordering::Greater));
327            };
328
329            match vm_try!(Value::partial_cmp_with(a, b, caller)) {
330                Some(Ordering::Equal) => continue,
331                other => return VmResult::Ok(other),
332            }
333        }
334
335        if b.next().is_some() {
336            return VmResult::Ok(Some(Ordering::Less));
337        }
338
339        VmResult::Ok(Some(Ordering::Equal))
340    }
341
342    pub(crate) fn cmp_with(
343        a: &[Value],
344        b: &[Value],
345        caller: &mut dyn ProtocolCaller,
346    ) -> VmResult<Ordering> {
347        let mut b = b.iter();
348
349        for a in a.iter() {
350            let Some(b) = b.next() else {
351                return VmResult::Ok(Ordering::Greater);
352            };
353
354            match vm_try!(Value::cmp_with(a, b, caller)) {
355                Ordering::Equal => continue,
356                other => return VmResult::Ok(other),
357            }
358        }
359
360        if b.next().is_some() {
361            return VmResult::Ok(Ordering::Less);
362        }
363
364        VmResult::Ok(Ordering::Equal)
365    }
366
367    /// This is a common get implementation that can be used across linear
368    /// types, such as vectors and tuples.
369    pub(crate) fn index_get(this: &[Value], index: Value) -> VmResult<Option<Value>> {
370        let slice: Option<&[Value]> = 'out: {
371            if let Some(value) = index.as_any() {
372                match value.type_hash() {
373                    RangeFrom::HASH => {
374                        let range = vm_try!(value.borrow_ref::<RangeFrom>());
375                        let start = vm_try!(range.start.as_usize());
376                        break 'out this.get(start..);
377                    }
378                    RangeFull::HASH => {
379                        _ = vm_try!(value.borrow_ref::<RangeFull>());
380                        break 'out this.get(..);
381                    }
382                    RangeInclusive::HASH => {
383                        let range = vm_try!(value.borrow_ref::<RangeInclusive>());
384                        let start = vm_try!(range.start.as_usize());
385                        let end = vm_try!(range.end.as_usize());
386                        break 'out this.get(start..=end);
387                    }
388                    RangeToInclusive::HASH => {
389                        let range = vm_try!(value.borrow_ref::<RangeToInclusive>());
390                        let end = vm_try!(range.end.as_usize());
391                        break 'out this.get(..=end);
392                    }
393                    RangeTo::HASH => {
394                        let range = vm_try!(value.borrow_ref::<RangeTo>());
395                        let end = vm_try!(range.end.as_usize());
396                        break 'out this.get(..end);
397                    }
398                    Range::HASH => {
399                        let range = vm_try!(value.borrow_ref::<Range>());
400                        let start = vm_try!(range.start.as_usize());
401                        let end = vm_try!(range.end.as_usize());
402                        break 'out this.get(start..end);
403                    }
404                    _ => {}
405                }
406            };
407
408            let index = vm_try!(usize::from_value(index));
409
410            let Some(value) = this.get(index) else {
411                return VmResult::Ok(None);
412            };
413
414            return VmResult::Ok(Some(value.clone()));
415        };
416
417        let Some(values) = slice else {
418            return VmResult::Ok(None);
419        };
420
421        let vec = vm_try!(alloc::Vec::try_from(values));
422        VmResult::Ok(Some(vm_try!(Value::vec(vec))))
423    }
424
425    #[cfg(feature = "alloc")]
426    pub(crate) fn hash_with(
427        &self,
428        hasher: &mut Hasher,
429        caller: &mut dyn ProtocolCaller,
430    ) -> VmResult<()> {
431        for value in self.inner.iter() {
432            vm_try!(value.hash_with(hasher, caller));
433        }
434
435        VmResult::Ok(())
436    }
437}
438
439impl TryClone for Vec {
440    fn try_clone(&self) -> alloc::Result<Self> {
441        Ok(Self {
442            inner: self.inner.try_clone()?,
443        })
444    }
445}
446
447impl fmt::Debug for Vec {
448    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
449        f.debug_list().entries(&*self.inner).finish()
450    }
451}
452
453impl ops::Deref for Vec {
454    type Target = [Value];
455
456    #[inline]
457    fn deref(&self) -> &Self::Target {
458        &self.inner
459    }
460}
461
462impl ops::DerefMut for Vec {
463    #[inline]
464    fn deref_mut(&mut self) -> &mut Self::Target {
465        &mut self.inner
466    }
467}
468
469impl IntoIterator for Vec {
470    type Item = Value;
471    type IntoIter = alloc::vec::IntoIter<Value>;
472
473    #[inline]
474    fn into_iter(self) -> Self::IntoIter {
475        self.inner.into_iter()
476    }
477}
478
479impl<'a> IntoIterator for &'a Vec {
480    type Item = &'a Value;
481    type IntoIter = slice::Iter<'a, Value>;
482
483    #[inline]
484    fn into_iter(self) -> Self::IntoIter {
485        self.inner.iter()
486    }
487}
488
489impl<'a> IntoIterator for &'a mut Vec {
490    type Item = &'a mut Value;
491    type IntoIter = slice::IterMut<'a, Value>;
492
493    #[inline]
494    fn into_iter(self) -> Self::IntoIter {
495        self.inner.iter_mut()
496    }
497}
498
499#[cfg(feature = "alloc")]
500impl TryFrom<::rust_alloc::vec::Vec<Value>> for Vec {
501    type Error = alloc::Error;
502
503    #[inline]
504    fn try_from(values: ::rust_alloc::vec::Vec<Value>) -> Result<Self, Self::Error> {
505        let mut inner = alloc::Vec::try_with_capacity(values.len())?;
506
507        for value in values {
508            inner.try_push(value)?;
509        }
510
511        Ok(Self { inner })
512    }
513}
514
515#[cfg(feature = "alloc")]
516impl TryFrom<::rust_alloc::boxed::Box<[Value]>> for Vec {
517    type Error = alloc::Error;
518
519    #[inline]
520    fn try_from(inner: ::rust_alloc::boxed::Box<[Value]>) -> Result<Self, Self::Error> {
521        Vec::try_from(inner.into_vec())
522    }
523}
524
525impl From<alloc::Vec<Value>> for Vec {
526    #[inline]
527    fn from(inner: alloc::Vec<Value>) -> Self {
528        Self { inner }
529    }
530}
531
532#[cfg(feature = "alloc")]
533impl<T> FromValue for ::rust_alloc::vec::Vec<T>
534where
535    T: FromValue,
536{
537    #[inline]
538    fn from_value(value: Value) -> Result<Self, RuntimeError> {
539        let vec = value.downcast::<Vec>()?;
540
541        let mut output = ::rust_alloc::vec::Vec::with_capacity(vec.len());
542
543        for value in vec {
544            output.push(T::from_value(value)?);
545        }
546
547        Ok(output)
548    }
549}
550
551impl<T> FromValue for alloc::Vec<T>
552where
553    T: FromValue,
554{
555    #[inline]
556    fn from_value(value: Value) -> Result<Self, RuntimeError> {
557        let vec = value.downcast::<Vec>()?;
558
559        let mut output = alloc::Vec::try_with_capacity(vec.len())?;
560
561        for value in vec {
562            output.try_push(T::from_value(value)?)?;
563        }
564
565        Ok(output)
566    }
567}
568
569impl UnsafeToRef for [Value] {
570    type Guard = RawAnyGuard;
571
572    #[inline]
573    unsafe fn unsafe_to_ref<'a>(value: Value) -> Result<(&'a Self, Self::Guard), RuntimeError> {
574        let vec = value.into_ref::<Vec>()?;
575        let (vec, guard) = Ref::into_raw(vec);
576        Ok((vec.as_ref().as_slice(), guard))
577    }
578}
579
580impl<T, const N: usize> ToValue for [T; N]
581where
582    T: ToValue,
583{
584    #[inline]
585    fn to_value(self) -> Result<Value, RuntimeError> {
586        let mut inner = alloc::Vec::try_with_capacity(self.len())?;
587
588        for value in self {
589            let value = value.to_value()?;
590            inner.try_push(value)?;
591        }
592
593        Ok(Value::try_from(Vec { inner })?)
594    }
595}
596
597impl<T> ToValue for alloc::Vec<T>
598where
599    T: ToValue,
600{
601    #[inline]
602    fn to_value(self) -> Result<Value, RuntimeError> {
603        let mut inner = alloc::Vec::try_with_capacity(self.len())?;
604
605        for value in self {
606            let value = value.to_value()?;
607            inner.try_push(value)?;
608        }
609
610        Ok(Value::try_from(Vec { inner })?)
611    }
612}
613
614#[cfg(feature = "alloc")]
615impl<T> ToValue for ::rust_alloc::vec::Vec<T>
616where
617    T: ToValue,
618{
619    #[inline]
620    fn to_value(self) -> Result<Value, RuntimeError> {
621        let mut inner = alloc::Vec::try_with_capacity(self.len())?;
622
623        for value in self {
624            let value = value.to_value()?;
625            inner.try_push(value)?;
626        }
627
628        Ok(Value::try_from(Vec { inner })?)
629    }
630}