Skip to main content

rune/runtime/
vec.rs

1use core::cmp;
2use core::cmp::Ordering;
3use core::fmt;
4use core::mem;
5use core::ops;
6use core::slice;
7use core::slice::SliceIndex;
8
9use crate as rune;
10use crate::alloc;
11use crate::alloc::fmt::TryWrite;
12use crate::alloc::prelude::*;
13use crate::runtime::slice::Iter;
14use crate::shared::FixedVec;
15use crate::{Any, TypeHash};
16
17use super::{
18    Dismantle, EnvProtocolCaller, Formatter, FromValue, Handover, Hasher, ProtocolCaller, Range,
19    RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive, RawAnyGuard, Ref,
20    RuntimeError, ToValue, UnsafeToRef, Value, VmError, VmErrorKind, Worklist,
21};
22
23/// Struct representing a dynamic vector.
24///
25/// # Examples
26///
27/// ```
28/// let mut vec = rune::runtime::Vec::new();
29/// assert!(vec.is_empty());
30///
31/// vec.push_value(42)?;
32/// vec.push_value(true)?;
33/// assert_eq!(2, vec.len());
34///
35/// assert_eq!(Some(42), vec.get_value(0)?);
36/// assert_eq!(Some(true), vec.get_value(1)?);
37/// assert_eq!(None::<bool>, vec.get_value(2)?);
38/// # Ok::<_, rune::support::Error>(())
39/// ```
40#[derive(Default, Any)]
41#[repr(transparent)]
42#[rune(item = ::std::vec, dismantle)]
43pub struct Vec {
44    inner: alloc::Vec<Value>,
45}
46
47/// A vector is made of the values put into it, and a script can nest one inside
48/// another without any bound, so it hands over what it is made of rather than
49/// being dropped in place.
50impl Dismantle for Vec {
51    fn dismantle(&mut self, out: &mut Handover<'_>) {
52        // Every value is handed over in one pass over the vector, and what is
53        // left of it is dropped as soon as this returns.
54        for value in self.inner.drain(..) {
55            out.push(value);
56        }
57    }
58}
59
60impl Vec {
61    /// Constructs a new, empty dynamic `Vec`.
62    ///
63    /// The vector will not allocate until elements are pushed onto it.
64    ///
65    /// # Examples
66    ///
67    /// ```
68    /// use rune::runtime::Vec;
69    ///
70    /// let mut vec = Vec::new();
71    /// ```
72    pub const fn new() -> Self {
73        Self {
74            inner: alloc::Vec::new(),
75        }
76    }
77
78    /// Sort the vector with the given comparison function.
79    ///
80    /// The comparison is made by whoever called this, which for a script is
81    /// whoever wrote the script, so it is under no obligation to implement a
82    /// total order. It can be inconsistent by accident, on purpose, or because
83    /// it failed and the caller substituted a placeholder ordering for the call
84    /// which failed.
85    ///
86    /// The standard library's sort notices such a comparison and panics, which
87    /// would take the host process with it, so this is a merge sort which
88    /// neither notices nor cares - an inconsistent comparison simply leaves the
89    /// elements in an order which is not worth describing. It is stable, and it
90    /// allocates its scratch space through the same allocator as everything
91    /// else, so a memory limit accounts for it.
92    pub fn sort_by<F>(&mut self, mut compare: F) -> alloc::Result<()>
93    where
94        F: FnMut(&Value, &Value) -> cmp::Ordering,
95    {
96        let len = self.inner.len();
97
98        if len < 2 {
99            return Ok(());
100        }
101
102        // Bottom-up merge sort, writing each pass into the other buffer.
103        let mut buf = self.inner.try_clone()?;
104        let mut width = 1usize;
105
106        while width < len {
107            let mut start = 0;
108
109            while start < len {
110                let mid = start.saturating_add(width).min(len);
111                let end = start.saturating_add(width * 2).min(len);
112
113                merge(
114                    &self.inner[start..mid],
115                    &self.inner[mid..end],
116                    &mut buf[start..end],
117                    &mut compare,
118                );
119
120                start = end;
121            }
122
123            mem::swap(&mut self.inner, &mut buf);
124            width *= 2;
125        }
126
127        Ok(())
128    }
129
130    /// Construct a new dynamic vector guaranteed to have at least the given
131    /// capacity.
132    pub fn with_capacity(cap: usize) -> alloc::Result<Self> {
133        Ok(Self {
134            inner: alloc::Vec::try_with_capacity(cap)?,
135        })
136    }
137
138    /// Convert into inner rune alloc vector.
139    pub fn into_inner(self) -> alloc::Vec<Value> {
140        self.inner
141    }
142
143    /// Returns `true` if the vector contains no elements.
144    ///
145    /// # Examples
146    ///
147    /// ```
148    /// use rune::runtime::{Value, Vec};
149    ///
150    /// let mut v = Vec::new();
151    /// assert!(v.is_empty());
152    ///
153    /// v.push(rune::to_value(1u32)?);
154    /// assert!(!v.is_empty());
155    /// # Ok::<_, rune::support::Error>(())
156    /// ```
157    pub fn is_empty(&self) -> bool {
158        self.inner.is_empty()
159    }
160
161    /// Returns the number of elements in the dynamic vector, also referred to
162    /// as its 'length'.
163    pub fn len(&self) -> usize {
164        self.inner.len()
165    }
166
167    /// Returns the number of elements in the dynamic vector, also referred to
168    /// as its 'length'.
169    pub fn capacity(&self) -> usize {
170        self.inner.capacity()
171    }
172
173    /// Set by index
174    pub fn set(&mut self, index: usize, value: Value) -> Result<(), VmError> {
175        let length = self.len();
176
177        let Some(v) = self.inner.get_mut(index) else {
178            return Err(VmError::new(VmErrorKind::OutOfRange {
179                index: index.into(),
180                length: length.into(),
181            }));
182        };
183
184        // The value which is replaced is taken apart rather than dropped in
185        // place. A native function has no worklist of its own to do that over,
186        // so it gets one which is empty - which costs nothing until it is
187        // handed a value made of other values.
188        Worklist::new().replace(v, value);
189        Ok(())
190    }
191
192    /// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
193    ///
194    /// If `new_len` is greater than `len`, the `Vec` is extended by the
195    /// difference, with each additional slot filled with `value`. If `new_len`
196    /// is less than `len`, the `Vec` is simply truncated.
197    pub fn resize(&mut self, new_len: usize, value: Value) -> Result<(), VmError> {
198        let len = self.inner.len();
199
200        if new_len < len {
201            // Shrinking discards the values past the new length, which are
202            // taken apart rather than dropped where they are.
203            if let Some(values) = self.inner.get_mut(new_len..) {
204                Worklist::new().dismantle_all(values.iter_mut());
205            }
206
207            self.inner.truncate(new_len);
208            return Ok(());
209        }
210
211        if value.is_inline() {
212            self.inner.try_resize(new_len, value)?;
213        } else {
214            for _ in 0..new_len - len {
215                let value = value.clone_with(&mut EnvProtocolCaller)?;
216                self.inner.try_push(value)?;
217            }
218        }
219
220        Ok(())
221    }
222
223    /// Take every value in the vector apart rather than dropping them where
224    /// they are - see [`Worklist::dismantle`].
225    pub(crate) fn dismantle(&mut self, work: &mut Worklist) {
226        work.dismantle_all(self.inner.iter_mut());
227        self.inner.clear();
228    }
229
230    /// Appends an element to the back of a dynamic vector.
231    pub fn push(&mut self, value: Value) -> alloc::Result<()> {
232        self.inner.try_push(value)
233    }
234
235    /// Appends an element to the back of a dynamic vector, converting it as
236    /// necessary through the [`ToValue`] trait.
237    pub fn push_value<T>(&mut self, value: T) -> Result<(), VmError>
238    where
239        T: ToValue,
240    {
241        self.inner.try_push(value.to_value()?)?;
242        Ok(())
243    }
244
245    /// Get the value at the given index.
246    pub fn get<I>(&self, index: I) -> Option<&I::Output>
247    where
248        I: SliceIndex<[Value]>,
249    {
250        self.inner.get(index)
251    }
252
253    /// Get the given value at the given index.
254    pub fn get_value<T>(&self, index: usize) -> Result<Option<T>, VmError>
255    where
256        T: FromValue,
257    {
258        let Some(value) = self.inner.get(index) else {
259            return Ok(None);
260        };
261
262        Ok(Some(T::from_value(value.clone())?))
263    }
264
265    /// Get the mutable value at the given index.
266    pub fn get_mut(&mut self, index: usize) -> Option<&mut Value> {
267        self.inner.get_mut(index)
268    }
269
270    /// Removes the last element from a dynamic vector and returns it, or
271    /// [`None`] if it is empty.
272    pub fn pop(&mut self) -> Option<Value> {
273        self.inner.pop()
274    }
275
276    /// Removes the element at the specified index from a dynamic vector.
277    pub fn remove(&mut self, index: usize) -> Value {
278        self.inner.remove(index)
279    }
280
281    /// Clears the vector, removing all values.
282    ///
283    /// Note that this method has no effect on the allocated capacity of the
284    /// vector.
285    pub fn clear(&mut self) {
286        self.inner.clear();
287    }
288
289    /// Inserts an element at position index within the vector, shifting all
290    /// elements after it to the right.
291    pub fn insert(&mut self, index: usize, value: Value) -> alloc::Result<()> {
292        self.inner.try_insert(index, value)
293    }
294
295    /// Extend this vector with something that implements the into_iter
296    /// protocol.
297    pub fn extend(&mut self, value: Value) -> Result<(), VmError> {
298        let mut it = value.into_iter()?;
299
300        while let Some(value) = it.next()? {
301            self.push(value)?;
302        }
303
304        Ok(())
305    }
306
307    /// Iterate over the vector.
308    ///
309    /// # Examples
310    ///
311    /// ```rune
312    /// let vec = [1, 2, 3, 4];
313    /// let it = vec.iter();
314    ///
315    /// assert_eq!(it.next(), Some(1));
316    /// assert_eq!(it.next_back(), Some(4));
317    /// ```
318    #[rune::function(keep, path = Self::iter)]
319    pub fn rune_iter(this: Ref<Self>) -> Iter {
320        Iter::new(Ref::map(this, |vec| &**vec))
321    }
322
323    /// Access the inner values as a slice.
324    pub(crate) fn as_slice(&self) -> &[Value] {
325        &self.inner
326    }
327
328    pub(crate) fn debug_fmt_with(
329        this: &[Value],
330        f: &mut Formatter,
331        caller: &mut dyn ProtocolCaller,
332    ) -> Result<(), VmError> {
333        let mut it = this.iter().peekable();
334        write!(f, "[")?;
335
336        while let Some(value) = it.next() {
337            value.debug_fmt_with(f, caller)?;
338
339            if it.peek().is_some() {
340                write!(f, ", ")?;
341            }
342        }
343
344        write!(f, "]")?;
345        Ok(())
346    }
347
348    pub(crate) fn partial_eq_with(
349        a: &[Value],
350        b: Value,
351        caller: &mut dyn ProtocolCaller,
352    ) -> Result<bool, VmError> {
353        let mut b = b.into_iter_with(caller)?;
354
355        for a in a {
356            let Some(b) = b.next()? else {
357                return Ok(false);
358            };
359
360            if !Value::partial_eq_with(a, &b, caller)? {
361                return Ok(false);
362            }
363        }
364
365        if b.next()?.is_some() {
366            return Ok(false);
367        }
368
369        Ok(true)
370    }
371
372    pub(crate) fn eq_with(
373        a: &[Value],
374        b: &[Value],
375        eq: fn(&Value, &Value, &mut dyn ProtocolCaller) -> Result<bool, VmError>,
376        caller: &mut dyn ProtocolCaller,
377    ) -> Result<bool, VmError> {
378        if a.len() != b.len() {
379            return Ok(false);
380        }
381
382        for (a, b) in a.iter().zip(b.iter()) {
383            if !eq(a, b, caller)? {
384                return Ok(false);
385            }
386        }
387
388        Ok(true)
389    }
390
391    pub(crate) fn partial_cmp_with(
392        a: &[Value],
393        b: &[Value],
394        caller: &mut dyn ProtocolCaller,
395    ) -> Result<Option<Ordering>, VmError> {
396        let mut b = b.iter();
397
398        for a in a.iter() {
399            let Some(b) = b.next() else {
400                return Ok(Some(Ordering::Greater));
401            };
402
403            match Value::partial_cmp_with(a, b, caller)? {
404                Some(Ordering::Equal) => continue,
405                other => return Ok(other),
406            }
407        }
408
409        if b.next().is_some() {
410            return Ok(Some(Ordering::Less));
411        }
412
413        Ok(Some(Ordering::Equal))
414    }
415
416    pub(crate) fn cmp_with(
417        a: &[Value],
418        b: &[Value],
419        caller: &mut dyn ProtocolCaller,
420    ) -> Result<Ordering, VmError> {
421        let mut b = b.iter();
422
423        for a in a.iter() {
424            let Some(b) = b.next() else {
425                return Ok(Ordering::Greater);
426            };
427
428            match Value::cmp_with(a, b, caller)? {
429                Ordering::Equal => continue,
430                other => return Ok(other),
431            }
432        }
433
434        if b.next().is_some() {
435            return Ok(Ordering::Less);
436        }
437
438        Ok(Ordering::Equal)
439    }
440
441    /// This is a common get implementation that can be used across linear
442    /// types, such as vectors and tuples.
443    pub(crate) fn index_get(this: &[Value], index: Value) -> Result<Option<Value>, VmError> {
444        let slice: Option<&[Value]> = 'out: {
445            if let Some(value) = index.as_any() {
446                match value.type_hash() {
447                    RangeFrom::HASH => {
448                        let range = value.borrow_ref::<RangeFrom>()?;
449                        let start = range.start.as_usize()?;
450                        break 'out this.get(start..);
451                    }
452                    RangeFull::HASH => {
453                        _ = value.borrow_ref::<RangeFull>()?;
454                        break 'out this.get(..);
455                    }
456                    RangeInclusive::HASH => {
457                        let range = value.borrow_ref::<RangeInclusive>()?;
458                        let start = range.start.as_usize()?;
459                        let end = range.end.as_usize()?;
460                        break 'out this.get(start..=end);
461                    }
462                    RangeToInclusive::HASH => {
463                        let range = value.borrow_ref::<RangeToInclusive>()?;
464                        let end = range.end.as_usize()?;
465                        break 'out this.get(..=end);
466                    }
467                    RangeTo::HASH => {
468                        let range = value.borrow_ref::<RangeTo>()?;
469                        let end = range.end.as_usize()?;
470                        break 'out this.get(..end);
471                    }
472                    Range::HASH => {
473                        let range = value.borrow_ref::<Range>()?;
474                        let start = range.start.as_usize()?;
475                        let end = range.end.as_usize()?;
476                        break 'out this.get(start..end);
477                    }
478                    _ => {}
479                }
480            };
481
482            let index = usize::from_value(index)?;
483
484            let Some(value) = this.get(index) else {
485                return Ok(None);
486            };
487
488            return Ok(Some(value.clone()));
489        };
490
491        let Some(values) = slice else {
492            return Ok(None);
493        };
494
495        let vec = alloc::Vec::try_from(values)?;
496        Ok(Some(Value::vec(vec)?))
497    }
498
499    pub(crate) fn hash_with(
500        &self,
501        hasher: &mut Hasher,
502        caller: &mut dyn ProtocolCaller,
503    ) -> Result<(), VmError> {
504        for value in self.inner.iter() {
505            value.hash_with(hasher, caller)?;
506        }
507
508        Ok(())
509    }
510}
511
512impl TryClone for Vec {
513    fn try_clone(&self) -> alloc::Result<Self> {
514        Ok(Self {
515            inner: self.inner.try_clone()?,
516        })
517    }
518}
519
520impl fmt::Debug for Vec {
521    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
522        f.debug_list().entries(&*self.inner).finish()
523    }
524}
525
526impl ops::Deref for Vec {
527    type Target = [Value];
528
529    #[inline]
530    fn deref(&self) -> &Self::Target {
531        &self.inner
532    }
533}
534
535impl ops::DerefMut for Vec {
536    #[inline]
537    fn deref_mut(&mut self) -> &mut Self::Target {
538        &mut self.inner
539    }
540}
541
542impl IntoIterator for Vec {
543    type Item = Value;
544    type IntoIter = alloc::vec::IntoIter<Value>;
545
546    #[inline]
547    fn into_iter(self) -> Self::IntoIter {
548        self.inner.into_iter()
549    }
550}
551
552impl<'a> IntoIterator for &'a Vec {
553    type Item = &'a Value;
554    type IntoIter = slice::Iter<'a, Value>;
555
556    #[inline]
557    fn into_iter(self) -> Self::IntoIter {
558        self.inner.iter()
559    }
560}
561
562impl<'a> IntoIterator for &'a mut Vec {
563    type Item = &'a mut Value;
564    type IntoIter = slice::IterMut<'a, Value>;
565
566    #[inline]
567    fn into_iter(self) -> Self::IntoIter {
568        self.inner.iter_mut()
569    }
570}
571
572impl TryFrom<rust_alloc::vec::Vec<Value>> for Vec {
573    type Error = alloc::Error;
574
575    #[inline]
576    fn try_from(values: rust_alloc::vec::Vec<Value>) -> Result<Self, Self::Error> {
577        let mut inner = alloc::Vec::try_with_capacity(values.len())?;
578
579        for value in values {
580            inner.try_push(value)?;
581        }
582
583        Ok(Self { inner })
584    }
585}
586
587impl TryFrom<rust_alloc::boxed::Box<[Value]>> for Vec {
588    type Error = alloc::Error;
589
590    #[inline]
591    fn try_from(inner: rust_alloc::boxed::Box<[Value]>) -> Result<Self, Self::Error> {
592        Vec::try_from(inner.into_vec())
593    }
594}
595
596impl From<alloc::Vec<Value>> for Vec {
597    #[inline]
598    fn from(inner: alloc::Vec<Value>) -> Self {
599        Self { inner }
600    }
601}
602
603impl<T> FromValue for rust_alloc::vec::Vec<T>
604where
605    T: FromValue,
606{
607    #[inline]
608    fn from_value(value: Value) -> Result<Self, RuntimeError> {
609        let vec = value.downcast::<Vec>()?;
610
611        let mut output = rust_alloc::vec::Vec::with_capacity(vec.len());
612
613        for value in vec {
614            output.push(T::from_value(value)?);
615        }
616
617        Ok(output)
618    }
619}
620
621impl<T> FromValue for alloc::Vec<T>
622where
623    T: FromValue,
624{
625    #[inline]
626    fn from_value(value: Value) -> Result<Self, RuntimeError> {
627        let vec = value.downcast::<Vec>()?;
628
629        let mut output = alloc::Vec::try_with_capacity(vec.len())?;
630
631        for value in vec {
632            output.try_push(T::from_value(value)?)?;
633        }
634
635        Ok(output)
636    }
637}
638
639impl UnsafeToRef for [Value] {
640    type Guard = RawAnyGuard;
641
642    #[inline]
643    unsafe fn unsafe_to_ref<'a>(value: Value) -> Result<(&'a Self, Self::Guard), RuntimeError> {
644        let vec = value.into_ref::<Vec>()?;
645        let (vec, guard) = Ref::into_raw(vec);
646        Ok((vec.as_ref().as_slice(), guard))
647    }
648}
649
650impl<T> ToValue for alloc::Vec<T>
651where
652    T: ToValue,
653{
654    #[inline]
655    fn to_value(self) -> Result<Value, RuntimeError> {
656        let mut inner = alloc::Vec::try_with_capacity(self.len())?;
657
658        for value in self {
659            let value = value.to_value()?;
660            inner.try_push(value)?;
661        }
662
663        Ok(Value::try_from(Vec { inner })?)
664    }
665}
666
667impl<T> ToValue for rust_alloc::vec::Vec<T>
668where
669    T: ToValue,
670{
671    #[inline]
672    fn to_value(self) -> Result<Value, RuntimeError> {
673        let mut inner = alloc::Vec::try_with_capacity(self.len())?;
674
675        for value in self {
676            let value = value.to_value()?;
677            inner.try_push(value)?;
678        }
679
680        Ok(Value::try_from(Vec { inner })?)
681    }
682}
683
684impl<T, const N: usize> FromValue for [T; N]
685where
686    T: FromValue,
687{
688    fn from_value(value: Value) -> Result<Self, RuntimeError> {
689        let vec = value.into_ref::<Vec>()?;
690
691        let values = vec.as_slice();
692
693        if values.len() != N {
694            return Err(RuntimeError::new(VmErrorKind::ExpectedVecLength {
695                actual: vec.len(),
696                expected: N,
697            }));
698        };
699
700        let mut output = FixedVec::<T, N>::new();
701
702        for v in values {
703            output.try_push(T::from_value(v.clone())?)?;
704        }
705
706        Ok(output.into_inner())
707    }
708}
709
710impl<T, const N: usize> ToValue for [T; N]
711where
712    T: ToValue,
713{
714    #[inline]
715    fn to_value(self) -> Result<Value, RuntimeError> {
716        let mut inner = alloc::Vec::try_with_capacity(self.len())?;
717
718        for value in self {
719            let value = value.to_value()?;
720            inner.try_push(value)?;
721        }
722
723        Ok(Value::try_from(Vec { inner })?)
724    }
725}
726
727/// Merge two runs which are already in order into `out`.
728///
729/// The comparison is only ever asked whether the left hand side should come
730/// after the right, and anything other than that keeps the left hand side
731/// first, which is what makes the sort stable and what keeps it from caring
732/// whether the comparison is consistent.
733fn merge<F>(a: &[Value], b: &[Value], out: &mut [Value], compare: &mut F)
734where
735    F: FnMut(&Value, &Value) -> Ordering,
736{
737    let mut i = 0;
738    let mut j = 0;
739
740    for slot in out.iter_mut() {
741        let take_a = if i >= a.len() {
742            false
743        } else if j >= b.len() {
744            true
745        } else {
746            !matches!(compare(&a[i], &b[j]), Ordering::Greater)
747        };
748
749        if take_a {
750            *slot = a[i].clone();
751            i += 1;
752        } else {
753            *slot = b[j].clone();
754            j += 1;
755        }
756    }
757}