std/dynamic
Import with import std/dynamic.
Exports
Section titled “Exports”type Dynamic
Section titled “type Dynamic”type Dynamic
Opaque wrapper for a value of unknown shape returned by an extern function or decoded from an external source such as JSON, YAML, RPC payloads, or database rows.
Dynamic values are produced by externs that declare Dynamic in their
return type. Pure Nomi code cannot construct one directly. To pass a typed
Nomi value to host code as a dynamic value, call an extern that accepts a
Dynamic argument and let the runtime marshal it for the host.
Inspect via Dynamic.field/index/path navigators and
Dynamic.as_string/as_int/… extractors. Each step returns
Result<_, DecodeError> with a structured path; chain with try
to propagate.
Dynamic.field
Section titled “Dynamic.field”fn field(d: Dynamic, name: String): Result<Dynamic, DecodeError>
type function on Dynamic
Drill into a struct/dict-shaped Dynamic by field name. Fails with
expected="object with field <name>" if d is a dict but doesn’t
have the field, or expected="object" if d is not a dict at all.
Dynamic.index
Section titled “Dynamic.index”fn index(d: Dynamic, i: Int): Result<Dynamic, DecodeError>
type function on Dynamic
Drill into a list-shaped Dynamic by zero-based index. Fails with
expected="list with at least <i+1> elements" if d is a list but
the index is out of bounds, or expected="list" if d is not a
list at all.
Dynamic.path
Section titled “Dynamic.path”fn path(d: Dynamic, dotted: String): Result<Dynamic, DecodeError>
type function on Dynamic
Convenience: dotted-path navigator. Dynamic.path(d, "a.b.c") is
equivalent to
d |> Dynamic.field("a") |> try |> Dynamic.field("b") |> try |> Dynamic.field("c").
Does NOT support index notation (use index directly for lists).
Empty segments (e.g. "a..b") error.
Dynamic.as_string
Section titled “Dynamic.as_string”fn as_string(d: Dynamic): Result<String, DecodeError>
type function on Dynamic
Extract a Dynamic as a String. Err on type mismatch.
Dynamic.as_int
Section titled “Dynamic.as_int”fn as_int(d: Dynamic): Result<Int, DecodeError>
type function on Dynamic
Extract a Dynamic as an Int. Accepts integer-shaped Floats (e.g. JSON’s number 36.0) but rejects values with a fractional part.
Dynamic.as_float
Section titled “Dynamic.as_float”fn as_float(d: Dynamic): Result<Float, DecodeError>
type function on Dynamic
Extract a Dynamic as a Float. Accepts Ints (widening) and Floats.
Dynamic.as_bool
Section titled “Dynamic.as_bool”fn as_bool(d: Dynamic): Result<Bool, DecodeError>
type function on Dynamic
Extract a Dynamic as a Bool. Err on type mismatch.
Dynamic.as_list
Section titled “Dynamic.as_list”fn as_list(d: Dynamic): Result<List<Dynamic>, DecodeError>
type function on Dynamic
Extract a Dynamic as List<Dynamic> — each element is still
wrapped, so per-element decoding (List.map_result(decode_one))
composes through as_list. Err if d is not a list.
Dynamic.as_dict
Section titled “Dynamic.as_dict”fn as_dict(d: Dynamic): Result<Map<String, Dynamic>, DecodeError>
type function on Dynamic
Extract a Dynamic as Map<String, Dynamic> — each value is still
wrapped, so per-value decoding (map iteration + as_X) composes.
Err if d is not a dict/object.
Dynamic.null?
Section titled “Dynamic.null?”fn null?(d: Dynamic): Bool
type function on Dynamic
True iff d represents a null/nil value at the source (JSON null, Go nil, etc.). Never errors.
Dynamic.has?
Section titled “Dynamic.has?”fn has?(d: Dynamic, name: String): Bool
type function on Dynamic
True iff d is a dict and contains the named field. False otherwise (including when d is not a dict). Never errors.
Dynamic.as_maybe
Section titled “Dynamic.as_maybe”fn as_maybe<'T>(d: Dynamic, sub: (Dynamic) -> Result<'T, DecodeError>): Result<Maybe<'T>, DecodeError>
type function on Dynamic
Apply sub to d only if d is non-null. Null → Ok(None);
present → Ok(Some(try sub(d))).
The ergonomic helper for JSON’s ubiquitous nullable fields.
d |> Dynamic.as_maybe(Dynamic.as_string) |> try // → Maybe<String> from the value (or None if null).
Dynamic.at_field
Section titled “Dynamic.at_field”fn at_field<'T>(d: Dynamic, name: String, sub: (Dynamic) -> Result<'T, DecodeError>): Result<'T, DecodeError>
type function on Dynamic
Navigate into a struct/dict field AND apply a sub-decoder, accumulating the path segment on any error the sub-decoder returns. The chain
d |> Dynamic.at_field("user", |inner| inner |> Dynamic.at_field("address", |inner2| inner2 |> Dynamic.at_field("zip", Dynamic.as_int)))
produces a DecodeError with path = [Field("user"), Field("address"), Field("zip")] if as_int fails, vs. the raw
form
d |> Dynamic.field("user") |> try |> Dynamic.field("address") |> try |> Dynamic.field("zip") |> try |> Dynamic.as_int()
which produces an empty-path error because try returns Err
unchanged. Use this when you want path-rich diagnostics; the raw
form stays available when you don’t.
Field-missing failures from the navigator itself pass through
unchanged — they already carry [Field(name)] from field’s own
error, so the path is not doubled.
Dynamic.at_index
Section titled “Dynamic.at_index”fn at_index<'T>(d: Dynamic, i: Int, sub: (Dynamic) -> Result<'T, DecodeError>): Result<'T, DecodeError>
type function on Dynamic
List-index counterpart to at_field. Same path-accumulation
behaviour: prepends Index(i) to any error the sub-decoder
returns; navigator failures (out-of-bounds, non-list) pass
through unchanged.
Dynamic.inspect
Section titled “Dynamic.inspect”impl Debug
fn inspect(d: Dynamic): String
impl Debug.inspect
enum PathSegment
Section titled “enum PathSegment”enum PathSegment { Field String Index Int }
One segment of a DecodeError’s path. Field for a dict-key
navigation, Index for a list-index navigation.
PathSegment.to_string
Section titled “PathSegment.to_string”impl Display
fn to_string(value: PathSegment): String
impl Display.to_string
PathSegment.inspect
Section titled “PathSegment.inspect”impl Debug
fn inspect(value: PathSegment): String
impl Debug.inspect
struct DecodeError
Section titled “struct DecodeError”struct DecodeError { path: List<PathSegment> expected: String got: String }
Structured decode failure. path locates the failure site; one
segment per navigator that contributed to this error. Raw try
chains short-circuit on Err unchanged, so a chain like
d |> Dynamic.field("a") |> try |> Dynamic.field("b") |> try |> Dynamic.as_int()
produces an empty-path error if as_int fails — the outer navigators
never see the inner error to prepend their segment. Use at_field
/ at_index
when you want path-rich diagnostics; those combinators wrap a
navigator + sub-extractor and prepend the path segment on any
error the sub-extractor returns.
expected and got name the type mismatch.
DecodeError.to_string
Section titled “DecodeError.to_string”impl Display
fn to_string(e: DecodeError): String
impl Display.to_string
DecodeError.inspect
Section titled “DecodeError.inspect”impl Debug
fn inspect(value: DecodeError): String
impl Debug.inspect