Skip to main content

shape_vm/executor/utils/
extraction_helpers.rs

1//! Extraction helpers to reduce duplication across method handlers.
2//!
3//! Common patterns like "get array from first arg" and "coerce ValueWord to string"
4//! are centralized here so every call site is a single function call.
5
6use shape_value::{ArrayView, VMError, ValueWord};
7
8/// Extract a unified array view from the first element of `args`.
9/// Handles all array variants: generic Array, IntArray, FloatArray, BoolArray.
10#[inline]
11pub(crate) fn require_any_array_arg<'a>(args: &'a [ValueWord]) -> Result<ArrayView<'a>, VMError> {
12    args.first()
13        .ok_or(VMError::StackUnderflow)?
14        .as_any_array()
15        .ok_or_else(|| VMError::TypeError {
16            expected: "array",
17            got: "other",
18        })
19}
20
21/// Coerce a ValueWord value to a String representation.
22///
23/// Handles: string, f64, i64, bool, none → "null", fallback → Debug format.
24/// This replaces the 13-line pattern found in join_str, array_sort, etc.
25#[inline]
26pub(crate) fn nb_to_string_coerce(nb: &ValueWord) -> String {
27    if let Some(s) = nb.as_str() {
28        s.to_string()
29    } else if let Some(n) = nb.as_f64() {
30        n.to_string()
31    } else if let Some(i) = nb.as_i64() {
32        i.to_string()
33    } else if let Some(b) = nb.as_bool() {
34        b.to_string()
35    } else if nb.is_none() {
36        "null".to_string()
37    } else {
38        format!("{:?}", nb)
39    }
40}