shape-runtime 0.3.1

Bytecode compiler, builtins, and runtime infrastructure for Shape
Documentation
/// @module std::core::json_value
/// Typed JSON value ADT.
///
/// `json.parse(text)` returns `Result<Json>`. Pattern matching and
/// navigation methods provide typed access to unknown JSON structures.
/// `TryFrom<Json>` impls auto-derive `TryInto` so `as?` works:
///
///   let name = (data.get("name") as? string)?

/// Algebraic data type representing JSON values in Shape.
///
/// `Int` is used for JSON numbers that fit in `i64` and have no fractional
/// part; `Number` is used for everything else. This preserves the
/// `int` / `number` distinction at the boundary so downstream code can
/// recover the precise type without a follow-up coercion.
pub enum Json {
    Null,
    Bool(bool),
    Int(int),
    Number(number),
    Str(string),
    Array(any),
    Object(any),
}

extend Json {
    /// Access a field in a JSON object by key. Returns `Json::Null` for
    /// non-object values or missing keys.
    method get(key: string) -> Json {
        match self {
            Json::Object(obj) => {
                let result = __json_object_get(obj, key)
                result
            },
            _ => Json::Null,
        }
    }

    /// Access an element in a JSON array by index. Returns `Json::Null`
    /// for non-array values or out-of-range indices.
    method at(index: number) -> Json {
        match self {
            Json::Array(arr) => {
                let result = __json_array_at(arr, index)
                result
            },
            _ => Json::Null,
        }
    }

    /// Check if this value is `Json::Null`.
    method is_null() -> bool {
        match self {
            Json::Null => true,
            _ => false,
        }
    }

    /// Return the keys of a JSON object, or an empty array for non-objects.
    method keys() -> Array<string> {
        match self {
            Json::Object(obj) => __json_object_keys(obj),
            _ => [],
        }
    }

    /// Return the length of a JSON array or object, or 0.
    method len() -> number {
        match self {
            Json::Array(arr) => __json_array_len(arr),
            Json::Object(obj) => __json_object_len(obj),
            _ => 0,
        }
    }
}

impl TryFrom<Json> for string {
    method tryFrom(value: Json) -> Result<string, AnyError> {
        match value {
            Json::Str(s) => Ok(s),
            _ => Err("Json value is not a string"),
        }
    }
}

impl TryFrom<Json> for number {
    method tryFrom(value: Json) -> Result<number, AnyError> {
        match value {
            Json::Number(n) => Ok(n),
            Json::Int(i) => Ok(i as number),
            _ => Err("Json value is not a number"),
        }
    }
}

impl TryFrom<Json> for int {
    method tryFrom(value: Json) -> Result<int, AnyError> {
        match value {
            Json::Int(i) => Ok(i),
            _ => Err("Json value is not an int"),
        }
    }
}

impl TryFrom<Json> for bool {
    method tryFrom(value: Json) -> Result<bool, AnyError> {
        match value {
            Json::Bool(b) => Ok(b),
            _ => Err("Json value is not a bool"),
        }
    }
}