1use crate::{SemaError, Value};
9
10fn not_an_array(v: &Value, name: &str) -> SemaError {
11 SemaError::type_error("mutable-array", v.type_name())
12 .with_hint(format!("{name}: create one with (mutable-array/new)"))
13}
14
15pub fn mutable_array_get(
19 arr: &Value,
20 idx: &Value,
21 default: Option<&Value>,
22) -> Result<Value, SemaError> {
23 let a = arr
24 .as_mutable_array()
25 .ok_or_else(|| not_an_array(arr, "mutable-array/get"))?;
26 let idx = idx.as_index("mutable-array/get")?;
27 let items = a.items.borrow();
28 match items.get(idx) {
29 Some(v) => Ok(v.clone()),
30 None => match default {
31 Some(d) => Ok(d.clone()),
32 None => Err(SemaError::eval(format!(
33 "mutable-array/get: index {idx} out of bounds (length {})",
34 items.len()
35 ))),
36 },
37 }
38}
39
40pub fn mutable_array_set(arr: &Value, idx: &Value, val: Value) -> Result<(), SemaError> {
45 let a = arr
46 .as_mutable_array()
47 .ok_or_else(|| not_an_array(arr, "mutable-array/set!"))?;
48 let idx = idx.as_index("mutable-array/set!")?;
49 let mut items = a.items.borrow_mut();
50 let len = items.len();
51 match items.get_mut(idx) {
52 Some(slot) => {
53 *slot = val;
54 Ok(())
55 }
56 None => Err(SemaError::eval(format!(
57 "mutable-array/set!: index {idx} out of bounds (length {len})"
58 ))
59 .with_hint("set! writes to an existing slot; use mutable-array/push! to grow")),
60 }
61}