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