rune/modules/vec.rs
1//! The [`Vec`] dynamic vector.
2
3use core::cmp::Ordering;
4
5use crate as rune;
6use crate::alloc::prelude::*;
7use crate::runtime::slice::Iter;
8use crate::runtime::{
9 EnvProtocolCaller, Formatter, Function, Hasher, Ref, TypeOf, Value, Vec, VmErrorKind, VmResult,
10};
11use crate::{ContextError, Module};
12
13/// The [`Vec`] dynamic vector.
14///
15/// The vector type is a growable dynamic array that can hold an ordered
16/// collection of values.
17///
18/// Tuples in Rune are declared with the special `[a]` syntax, but can also be
19/// interacted with through the fundamental [`Vec`] type.
20///
21/// The vector type has support for native pattern matching:
22///
23/// ```rune
24/// let value = [1, 2];
25///
26/// if let [a, b] = value {
27/// assert_eq!(a, 1);
28/// assert_eq!(b, 2);
29/// }
30/// ```
31///
32/// # Examples
33///
34/// ```rune
35/// let empty = [];
36/// let one = [10];
37/// let two = [10, 20];
38///
39/// assert!(empty.is_empty());
40/// assert_eq!(one.0, 10);
41/// assert_eq!(two.0, 10);
42/// assert_eq!(two.1, 20);
43/// ```
44#[rune::module(::std::vec)]
45pub fn module() -> Result<Module, ContextError> {
46 let mut m = Module::from_meta(self::module_meta)?;
47
48 m.ty::<Vec>()?.docs(docstring! {
49 /// A dynamic vector.
50 ///
51 /// This is the type that is constructed in rune when an array expression such as `[1, 2, 3]` is used.
52 ///
53 /// # Comparisons
54 ///
55 /// Shorter sequences are considered smaller than longer ones, and vice versa.
56 ///
57 /// ```rune
58 /// assert!([1, 2, 3] < [1, 2, 3, 4]);
59 /// assert!([1, 2, 3] < [1, 2, 4]);
60 /// assert!([1, 2, 4] > [1, 2, 3]);
61 /// ```
62 })?;
63
64 m.function_meta(vec_new)?;
65 m.function_meta(vec_with_capacity)?;
66 m.function_meta(len)?;
67 m.function_meta(is_empty)?;
68 m.function_meta(capacity)?;
69 m.function_meta(get)?;
70 m.function_meta(clear)?;
71 m.function_meta(extend)?;
72 m.function_meta(Vec::rune_iter__meta)?;
73 m.function_meta(pop)?;
74 m.function_meta(push)?;
75 m.function_meta(remove)?;
76 m.function_meta(insert)?;
77 m.function_meta(sort_by)?;
78 m.function_meta(sort)?;
79 m.function_meta(into_iter__meta)?;
80 m.function_meta(index_get)?;
81 m.function_meta(index_set)?;
82 m.function_meta(resize)?;
83 m.function_meta(debug_fmt__meta)?;
84
85 m.function_meta(clone__meta)?;
86 m.implement_trait::<Vec>(rune::item!(::std::clone::Clone))?;
87
88 m.function_meta(partial_eq__meta)?;
89 m.implement_trait::<Vec>(rune::item!(::std::cmp::PartialEq))?;
90
91 m.function_meta(eq__meta)?;
92 m.implement_trait::<Vec>(rune::item!(::std::cmp::Eq))?;
93
94 m.function_meta(partial_cmp__meta)?;
95 m.implement_trait::<Vec>(rune::item!(::std::cmp::PartialOrd))?;
96
97 m.function_meta(cmp__meta)?;
98 m.implement_trait::<Vec>(rune::item!(::std::cmp::Ord))?;
99
100 m.function_meta(hash)?;
101 Ok(m)
102}
103
104/// Constructs a new, empty dynamic `Vec`.
105///
106/// The vector will not allocate until elements are pushed onto it.
107///
108/// # Examples
109///
110/// ```rune
111/// let vec = Vec::new();
112/// ```
113#[rune::function(free, path = Vec::new)]
114fn vec_new() -> Vec {
115 Vec::new()
116}
117
118/// Constructs a new, empty dynamic `Vec` with at least the specified capacity.
119///
120/// The vector will be able to hold at least `capacity` elements without
121/// reallocating. This method is allowed to allocate for more elements than
122/// `capacity`. If `capacity` is 0, the vector will not allocate.
123///
124/// It is important to note that although the returned vector has the minimum
125/// *capacity* specified, the vector will have a zero *length*. For an
126/// explanation of the difference between length and capacity, see *[Capacity
127/// and reallocation]*.
128///
129/// If it is important to know the exact allocated capacity of a `Vec`, always
130/// use the [`capacity`] method after construction.
131///
132/// [Capacity and reallocation]: #capacity-and-reallocation
133/// [`capacity`]: Vec::capacity
134///
135/// # Panics
136///
137/// Panics if the new capacity exceeds `isize::MAX` bytes.
138///
139/// # Examples
140///
141/// ```rune
142/// let vec = Vec::with_capacity(10);
143///
144/// // The vector contains no items, even though it has capacity for more
145/// assert_eq!(vec.len(), 0);
146/// assert!(vec.capacity() >= 10);
147///
148/// // These are all done without reallocating...
149/// for i in 0..10 {
150/// vec.push(i);
151/// }
152///
153/// assert_eq!(vec.len(), 10);
154/// assert!(vec.capacity() >= 10);
155///
156/// // ...but this may make the vector reallocate
157/// vec.push(11);
158/// assert_eq!(vec.len(), 11);
159/// assert!(vec.capacity() >= 11);
160/// ```
161#[rune::function(free, path = Vec::with_capacity)]
162fn vec_with_capacity(capacity: usize) -> VmResult<Vec> {
163 VmResult::Ok(vm_try!(Vec::with_capacity(capacity)))
164}
165
166/// Returns the number of elements in the vector, also referred to as its
167/// 'length'.
168///
169/// # Examples
170///
171/// ```rune
172/// let a = [1, 2, 3];
173/// assert_eq!(a.len(), 3);
174/// ```
175#[rune::function(instance)]
176fn len(vec: &Vec) -> usize {
177 vec.len()
178}
179
180/// Returns `true` if the vector contains no elements.
181///
182/// # Examples
183///
184/// ```rune
185/// let v = Vec::new();
186/// assert!(v.is_empty());
187///
188/// v.push(1);
189/// assert!(!v.is_empty());
190/// ```
191#[rune::function(instance)]
192fn is_empty(vec: &Vec) -> bool {
193 vec.is_empty()
194}
195
196/// Returns the total number of elements the vector can hold without
197/// reallocating.
198///
199/// # Examples
200///
201/// ```rune
202/// let vec = Vec::with_capacity(10);
203/// vec.push(42);
204/// assert!(vec.capacity() >= 10);
205/// ```
206#[rune::function(instance)]
207fn capacity(vec: &Vec) -> usize {
208 vec.capacity()
209}
210
211/// Returns a reference to an element or subslice depending on the type of
212/// index.
213///
214/// - If given a position, returns a reference to the element at that position
215/// or `None` if out of bounds.
216/// - If given a range, returns the subslice corresponding to that range, or
217/// `None` if out of bounds.
218///
219/// # Examples
220///
221/// ```rune
222/// let v = [1, 4, 3];
223/// assert_eq!(Some(4), v.get(1));
224/// assert_eq!(Some([1, 4]), v.get(0..2));
225/// assert_eq!(Some([1, 4, 3]), v.get(0..=2));
226/// assert_eq!(Some([1, 4, 3]), v.get(0..));
227/// assert_eq!(Some([1, 4, 3]), v.get(..));
228/// assert_eq!(Some([4, 3]), v.get(1..));
229/// assert_eq!(None, v.get(3));
230/// assert_eq!(None, v.get(0..4));
231/// ```
232#[rune::function(instance)]
233fn get(this: &Vec, index: Value) -> VmResult<Option<Value>> {
234 Vec::index_get(this, index)
235}
236
237/// Sort a vector by the specified comparator function.
238///
239/// # Examples
240///
241/// ```rune
242/// use std::ops::cmp;
243///
244/// let values = [1, 2, 3];
245/// values.sort_by(|a, b| cmp(b, a))
246/// ```
247#[rune::function(instance)]
248fn sort_by(vec: &mut Vec, comparator: &Function) -> VmResult<()> {
249 let mut error = None;
250
251 vec.sort_by(|a, b| match comparator.call::<Ordering>((a, b)) {
252 VmResult::Ok(ordering) => ordering,
253 VmResult::Err(e) => {
254 if error.is_none() {
255 error = Some(e);
256 }
257
258 Ordering::Equal
259 }
260 });
261
262 if let Some(e) = error {
263 VmResult::Err(e)
264 } else {
265 VmResult::Ok(())
266 }
267}
268
269/// Sort the vector.
270///
271/// This require all elements to be of the same type, and implement total
272/// ordering per the [`CMP`] protocol.
273///
274/// # Panics
275///
276/// If any elements present are not comparable, this method will panic.
277///
278/// This will panic because a tuple and a string are not comparable:
279///
280/// ```rune,should_panic
281/// let values = [(3, 1), "hello"];
282/// values.sort();
283/// ```
284///
285/// This too will panic because floating point values which do not have a total
286/// ordering:
287///
288/// ```rune,should_panic
289/// let values = [1.0, 2.0, f64::NAN];
290/// values.sort();
291/// ```
292///
293/// # Examples
294///
295/// ```rune
296/// let values = [3, 2, 1];
297/// values.sort();
298/// assert_eq!(values, [1, 2, 3]);
299///
300/// let values = [(3, 1), (2, 1), (1, 1)];
301/// values.sort();
302/// assert_eq!(values, [(1, 1), (2, 1), (3, 1)]);
303/// ```
304#[rune::function(instance)]
305fn sort(vec: &mut Vec) -> VmResult<()> {
306 let mut err = None;
307
308 vec.sort_by(|a, b| {
309 let result: VmResult<Ordering> = Value::cmp(a, b);
310
311 match result {
312 VmResult::Ok(cmp) => cmp,
313 VmResult::Err(e) => {
314 if err.is_none() {
315 err = Some(e);
316 }
317
318 // NB: fall back to sorting by address.
319 (a as *const _ as usize).cmp(&(b as *const _ as usize))
320 }
321 }
322 });
323
324 if let Some(err) = err {
325 return VmResult::Err(err);
326 }
327
328 VmResult::Ok(())
329}
330
331/// Clears the vector, removing all values.
332///
333/// Note that this method has no effect on the allocated capacity of the vector.
334///
335/// # Examples
336///
337/// ```rune
338/// let v = [1, 2, 3];
339///
340/// v.clear();
341///
342/// assert!(v.is_empty());
343/// ```
344#[rune::function(instance)]
345fn clear(vec: &mut Vec) {
346 vec.clear();
347}
348
349/// Extend these bytes with another collection.
350///
351/// # Examples
352///
353/// ```rune
354/// let vec = [1, 2, 3, 4];
355/// vec.extend([5, 6, 7, 8]);
356/// assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7, 8]);
357/// ```
358#[rune::function(instance)]
359fn extend(this: &mut Vec, value: Value) -> VmResult<()> {
360 this.extend(value)
361}
362
363/// Removes the last element from a vector and returns it, or [`None`] if it is
364/// empty.
365///
366/// If you'd like to pop the first element, consider using
367/// [`VecDeque::pop_front`] instead.
368///
369/// [`VecDeque::pop_front`]: crate::collections::VecDeque::pop_front
370///
371/// # Examples
372///
373/// ```rune
374/// let vec = [1, 2, 3];
375/// assert_eq!(vec.pop(), Some(3));
376/// assert_eq!(vec, [1, 2]);
377/// ```
378#[rune::function(instance)]
379fn pop(this: &mut Vec) -> Option<Value> {
380 this.pop()
381}
382
383/// Appends an element to the back of a collection.
384///
385/// # Panics
386///
387/// Panics if the new capacity exceeds `isize::MAX` bytes.
388///
389/// # Examples
390///
391/// ```rune
392/// let vec = [1, 2];
393/// vec.push(3);
394/// assert_eq!(vec, [1, 2, 3]);
395/// ```
396#[rune::function(instance)]
397fn push(this: &mut Vec, value: Value) -> VmResult<()> {
398 vm_try!(this.push(value));
399 VmResult::Ok(())
400}
401
402/// Removes and returns the element at position `index` within the vector,
403/// shifting all elements after it to the left.
404///
405/// Note: Because this shifts over the remaining elements, it has a worst-case
406/// performance of *O*(*n*). If you don't need the order of elements to be
407/// preserved, use [`swap_remove`] instead. If you'd like to remove elements
408/// from the beginning of the `Vec`, consider using [`VecDeque::pop_front`]
409/// instead.
410///
411/// [`swap_remove`]: Vec::swap_remove
412/// [`VecDeque::pop_front`]: crate::collections::VecDeque::pop_front
413///
414/// # Panics
415///
416/// Panics if `index` is out of bounds.
417///
418/// ```rune,should_panic
419/// let v = [1, 2, 3];
420/// v.remove(3);
421/// ```
422///
423/// # Examples
424///
425/// ```rune
426/// let v = [1, 2, 3];
427/// assert_eq!(v.remove(1), 2);
428/// assert_eq!(v, [1, 3]);
429/// ```
430#[rune::function(instance)]
431fn remove(this: &mut Vec, index: usize) -> VmResult<Value> {
432 if index >= this.len() {
433 return VmResult::err(VmErrorKind::OutOfRange {
434 index: index.into(),
435 length: this.len().into(),
436 });
437 }
438
439 let value = this.remove(index);
440 VmResult::Ok(value)
441}
442
443/// Inserts an element at position `index` within the vector, shifting all
444/// elements after it to the right.
445///
446/// # Panics
447///
448/// Panics if `index > len`.
449///
450/// # Examples
451///
452/// ```rune
453/// let vec = [1, 2, 3];
454/// vec.insert(1, 4);
455/// assert_eq!(vec, [1, 4, 2, 3]);
456/// vec.insert(4, 5);
457/// assert_eq!(vec, [1, 4, 2, 3, 5]);
458/// ```
459#[rune::function(instance)]
460fn insert(this: &mut Vec, index: usize, value: Value) -> VmResult<()> {
461 if index > this.len() {
462 return VmResult::err(VmErrorKind::OutOfRange {
463 index: index.into(),
464 length: this.len().into(),
465 });
466 }
467
468 vm_try!(this.insert(index, value));
469 VmResult::Ok(())
470}
471
472/// Clone the vector.
473///
474/// # Examples
475///
476/// ```rune
477/// let a = [1, 2, 3];
478/// let b = a.clone();
479///
480/// b.push(4);
481///
482/// assert_eq!(a, [1, 2, 3]);
483/// assert_eq!(b, [1, 2, 3, 4]);
484/// ```
485#[rune::function(keep, instance, protocol = CLONE)]
486fn clone(this: &Vec) -> VmResult<Vec> {
487 VmResult::Ok(vm_try!(this.try_clone()))
488}
489
490/// Construct an iterator over the tuple.
491///
492/// # Examples
493///
494/// ```rune
495/// let vec = [1, 2, 3];
496/// let out = [];
497///
498/// for v in vec {
499/// out.push(v);
500/// }
501///
502/// assert_eq!(out, [1, 2, 3]);
503/// ```
504#[rune::function(keep, instance, protocol = INTO_ITER)]
505fn into_iter(this: Ref<Vec>) -> Iter {
506 Vec::rune_iter(this)
507}
508
509/// Returns a reference to an element or subslice depending on the type of
510/// index.
511///
512/// - If given a position, returns a reference to the element at that position
513/// or `None` if out of bounds.
514/// - If given a range, returns the subslice corresponding to that range, or
515/// `None` if out of bounds.
516///
517/// # Panics
518///
519/// Panics if the specified `index` is out of range.
520///
521/// ```rune,should_panic
522/// let v = [10, 40, 30];
523/// assert_eq!(None, v[1..4]);
524/// ```
525///
526/// ```rune,should_panic
527/// let v = [10, 40, 30];
528/// assert_eq!(None, v[3]);
529/// ```
530///
531/// # Examples
532///
533/// ```rune
534/// let v = [10, 40, 30];
535/// assert_eq!(40, v[1]);
536/// assert_eq!([10, 40], v[0..2]);
537/// ```
538#[rune::function(instance, protocol = INDEX_GET)]
539fn index_get(this: &Vec, index: Value) -> VmResult<Value> {
540 let Some(value) = vm_try!(Vec::index_get(this, index)) else {
541 return VmResult::err(VmErrorKind::MissingIndex {
542 target: Vec::type_info(),
543 });
544 };
545
546 VmResult::Ok(value)
547}
548
549/// Inserts a value into the vector.
550///
551/// # Examples
552///
553/// ```rune
554/// let vec = [1, 2, 3];
555/// vec[0] = "a";
556/// assert_eq!(vec, ["a", 2, 3]);
557/// ```
558#[rune::function(instance, protocol = INDEX_SET)]
559fn index_set(this: &mut Vec, index: usize, value: Value) -> VmResult<()> {
560 Vec::set(this, index, value)
561}
562
563/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
564///
565/// If `new_len` is greater than `len`, the `Vec` is extended by the difference,
566/// with each additional slot filled with `value`. If `new_len` is less than
567/// `len`, the `Vec` is simply truncated.
568///
569/// This method requires `T` to implement [`Clone`], in order to be able to
570/// clone the passed value. If you need more flexibility (or want to rely on
571/// [`Default`] instead of [`Clone`]), use [`Vec::resize_with`]. If you only
572/// need to resize to a smaller size, use [`Vec::truncate`].
573///
574/// # Examples
575///
576/// ```rune
577/// let vec = ["hello"];
578/// vec.resize(3, "world");
579/// assert_eq!(vec, ["hello", "world", "world"]);
580///
581/// let vec = [1, 2, 3, 4];
582/// vec.resize(2, 0);
583/// assert_eq!(vec, [1, 2]);
584/// ```
585///
586/// Resizing calls `CLONE` each new element, which means they are not
587/// structurally shared:
588///
589/// ```rune
590/// let inner = [1];
591/// let vec = [2];
592/// vec.resize(3, inner);
593///
594/// inner.push(3);
595/// vec[1].push(4);
596///
597/// assert_eq!(vec, [2, [1, 4], [1]]);
598/// ```
599#[rune::function(instance)]
600fn resize(this: &mut Vec, new_len: usize, value: Value) -> VmResult<()> {
601 Vec::resize(this, new_len, value)
602}
603
604/// Write a debug representation to a string.
605///
606/// This calls the [`DEBUG_FMT`] protocol over all elements of the
607/// collection.
608///
609/// # Examples
610///
611/// ```rune
612/// let vec = [1, 2, 3];
613/// assert_eq!(format!("{:?}", vec), "[1, 2, 3]");
614/// ```
615#[rune::function(keep, instance, protocol = DEBUG_FMT)]
616fn debug_fmt(this: &Vec, f: &mut Formatter) -> VmResult<()> {
617 Vec::debug_fmt_with(this, f, &mut EnvProtocolCaller)
618}
619
620/// Perform a partial equality check with this vector.
621///
622/// This can take any argument which can be converted into an iterator using
623/// [`INTO_ITER`].
624///
625/// # Examples
626///
627/// ```rune
628/// let vec = [1, 2, 3];
629///
630/// assert!(vec == [1, 2, 3]);
631/// assert!(vec == (1..=3));
632/// assert!(vec != [2, 3, 4]);
633/// ```
634#[rune::function(keep, instance, protocol = PARTIAL_EQ)]
635fn partial_eq(this: &Vec, other: Value) -> VmResult<bool> {
636 Vec::partial_eq_with(this, other, &mut EnvProtocolCaller)
637}
638
639/// Perform a total equality check with this vector.
640///
641/// # Examples
642///
643/// ```rune
644/// use std::ops::eq;
645///
646/// let vec = [1, 2, 3];
647///
648/// assert!(eq(vec, [1, 2, 3]));
649/// assert!(!eq(vec, [2, 3, 4]));
650/// ```
651#[rune::function(keep, instance, protocol = EQ)]
652fn eq(this: &Vec, other: &Vec) -> VmResult<bool> {
653 Vec::eq_with(this, other, Value::eq_with, &mut EnvProtocolCaller)
654}
655
656/// Perform a partial comparison check with this vector.
657///
658/// # Examples
659///
660/// ```rune
661/// let vec = [1, 2, 3];
662///
663/// assert!(vec > [0, 2, 3]);
664/// assert!(vec < [2, 2, 3]);
665/// ```
666#[rune::function(keep, instance, protocol = PARTIAL_CMP)]
667fn partial_cmp(this: &Vec, other: &Vec) -> VmResult<Option<Ordering>> {
668 Vec::partial_cmp_with(this, other, &mut EnvProtocolCaller)
669}
670
671/// Perform a total comparison check with this vector.
672///
673/// # Examples
674///
675/// ```rune
676/// use std::cmp::Ordering;
677/// use std::ops::cmp;
678///
679/// let vec = [1, 2, 3];
680///
681/// assert_eq!(cmp(vec, [0, 2, 3]), Ordering::Greater);
682/// assert_eq!(cmp(vec, [2, 2, 3]), Ordering::Less);
683/// ```
684#[rune::function(keep, instance, protocol = CMP)]
685fn cmp(this: &Vec, other: &Vec) -> VmResult<Ordering> {
686 Vec::cmp_with(this, other, &mut EnvProtocolCaller)
687}
688
689/// Calculate the hash of a vector.
690///
691/// # Examples
692///
693/// ```rune
694/// use std::ops::hash;
695///
696/// assert_eq!(hash([0, 2, 3]), hash([0, 2, 3]));
697/// ```
698#[rune::function(instance, protocol = HASH)]
699fn hash(this: &Vec, hasher: &mut Hasher) -> VmResult<()> {
700 Vec::hash_with(this, hasher, &mut EnvProtocolCaller)
701}