compose_library/foundations/
array.rs1use crate::repr::Repr;
2use crate::{HeapRef, Iter, IterValue, Trace};
3use compose_library::diag::StrResult;
4use compose_library::{ArrayIter, Heap, UntypedRef, Value, Vm};
5use compose_macros::{func, scope, ty};
6use ecow::{eco_format, EcoString};
7use std::ops::{Deref, DerefMut};
8
9#[ty(scope, cast, name = "array")]
10#[derive(Debug, Clone, PartialEq)]
11pub struct ArrayValue(HeapRef<Array>);
12
13#[derive(Debug, Clone, PartialEq)]
14pub struct Array {
15 pub(crate) values: Vec<Value>,
16}
17
18impl From<Vec<Value>> for Array {
19 fn from(value: Vec<Value>) -> Self {
20 Self { values: value }
21 }
22}
23
24impl Deref for Array {
25 type Target = Vec<Value>;
26
27 fn deref(&self) -> &Self::Target {
28 &self.values
29 }
30}
31
32impl DerefMut for Array {
33 fn deref_mut(&mut self) -> &mut Self::Target {
34 &mut self.values
35 }
36}
37
38impl Array {
39 pub fn new() -> Self {
40 Self { values: Vec::new() }
41 }
42}
43
44impl Trace for Array {
45 fn visit_refs(&self, f: &mut dyn FnMut(UntypedRef)) {
46 for v in &self.values {
47 v.visit_refs(f);
48 }
49 }
50}
51
52impl ArrayValue {
53 pub fn new(heap: &mut Heap) -> Self {
54 Self(heap.alloc(Array::new()))
55 }
56
57 pub fn from(heap: &mut Heap, values: Vec<Value>) -> Self {
58 Self(heap.alloc(Array::from(values)))
59 }
60}
61
62impl Trace for ArrayValue {
63 fn visit_refs(&self, f: &mut dyn FnMut(UntypedRef)) {
64 f(self.0.key());
65 }
66}
67
68impl Repr for ArrayValue {
69 fn repr(&self, vm: &dyn Vm) -> EcoString {
70 let self_ = self.0.try_get(vm.heap()).expect("array value");
71
72 let items = self_.values.iter().map(|v| v.repr(vm)).collect::<Vec<_>>();
73
74 eco_format!("[{}]", items.join(", "))
75 }
76}
77
78impl ArrayValue {
79 pub(crate) fn try_get<'a>(&self, heap: &'a Heap) -> StrResult<&'a Array> {
80 self.0.try_get(heap)
81 }
82}
83
84#[scope]
85impl ArrayValue {
86 #[func]
87 fn len(&self, vm: &dyn Vm) -> StrResult<usize> {
88 Ok(self.0.try_get(vm.heap())?.len())
89 }
90
91 #[func]
92 fn is_empty(&self, vm: &dyn Vm) -> StrResult<bool> {
93 Ok(self.0.try_get(vm.heap())?.is_empty())
94 }
95
96 #[func]
97 fn push(&mut self, vm: &mut dyn Vm, value: Value) -> StrResult<()> {
98 let arr = self.0.try_get_mut(vm.heap_mut())?;
99
100 arr.push(value);
101
102 Ok(())
103 }
104
105 #[func]
106 fn pop(&mut self, vm: &mut dyn Vm) -> StrResult<Option<Value>> {
107 let arr = self.0.try_get_mut(vm.heap_mut())?;
108
109 Ok(arr.pop())
110 }
111
112 #[func]
113 pub fn shallow_clone(&self, vm: &mut dyn Vm) -> Self {
114 let clone = self.0.get_unwrap(vm.heap()).clone();
115
116 Self(vm.heap_mut().alloc(clone))
117 }
118
119 #[func]
120 pub fn iter(&self, vm: &mut dyn Vm) -> StrResult<IterValue> {
121 let arr = self.0.try_get(vm.heap())?;
122
123 let iter = Iter::Array(ArrayIter::new(arr));
124 Ok(IterValue::new(iter, vm))
125 }
126
127 #[func]
128 pub fn contains(&self, vm: &mut dyn Vm, value: Value) -> StrResult<bool> {
129 let arr = self.0.try_get(vm.heap())?;
130 Ok(arr.contains(&value))
131 }
132
133 #[func]
134 pub fn get(&self, vm: &mut dyn Vm, index: usize) -> StrResult<Option<Value>> {
135 let arr = self.0.try_get(vm.heap())?;
136 Ok(arr.get(index).cloned())
137 }
138}