Types
A value, mirrored. mirror produces it; every helper in this module reads it. Sum types stay faithful — some(5) is Some(Int(5)), not Int(5) — and a container that reaches itself mirrors as Ref(path) rather than diverging.
Void | The unit value. |
|---|---|
Bool(bool) | A boolean leaf. |
Int(int) | An integer leaf. |
Float(float) | A float leaf. |
Str(string) | A string leaf. |
Bytes(Bytes) | A byte buffer leaf. |
Arr([Mirror]) | Array elements, in order. |
Tup([Mirror]) | Tuple elements, in declaration order. |
Dict([(Mirror, Mirror)]) | Dictionary entries as key/value pairs, in insertion order. |
Struct(string, [(string, Mirror)]) | The declared type name, then its fields as name/value pairs in declaration order. |
Variant(string, string, Optional<string>, [Mirror]) | The enum's declared name, the variant name, its optional declared string value, then the payload slots in order. |
None | An |
Some(Mirror) | An |
Ok(Mirror) | A |
Err(string, string) | A failure's error name, then its message. |
Fn | A closure — opaque, with nothing to descend into. |
Future | A future — opaque. |
Chan | A channel — opaque. |
Iter | An iterator — opaque, since reading it would consume it. |
Ptr | A raw foreign pointer — opaque. |
Resource(string) | A native handle, named by its resource kind. |
Ref(string) | A back-edge: the path of the enclosing value this one points at, instead of an endless tree. |
Constants
Reflection kind tag for void values.
Reflection kind tag for bool values.
Reflection kind tag for int values.
Reflection kind tag for float values.
Reflection kind tag for str values.
Reflection kind tag for array values.
Reflection kind tag for dict values.
Reflection kind tag for struct values.
Reflection kind tag for enum values.
Reflection kind tag for none values.
Reflection kind tag for some values.
Reflection kind tag for bytes values.
Reflection kind tag for tuple values.
Reflection kind tag for other values.
Functions
value: Any value; runtime values are self-describing, so no type argument is needed.
struct Project { name: string, stars: int, active: bool }
fn main() {
let value = std.reflect.mirror(
Project { name: "moon", stars: 42, active: true },
)
println(std.reflect.type_name(value))
println(std.reflect.keys(value))
println(std.reflect.as_str(std.reflect.get(value, "name").unwrap()).unwrap())
println(std.reflect.as_int(std.reflect.at(value, 1).unwrap()).unwrap())
println(std.reflect.length(value))
println(std.reflect.entries(value).len())
println(std.reflect.paths(value).len())
println(std.reflect.has_cycle(value))
}Start a walk at value. Replaces any walk in progress.
value: The value to place the cursor on.
struct Point { x: int, y: int }
fn main() {
std.reflect.walk_begin(Point { x: 3, y: 4 })
println(std.reflect.kind_name(std.reflect.node_kind()))
println(std.reflect.node_type_name())
let mut index = 0
while index < std.reflect.node_len() {
println(std.reflect.node_field(index))
if std.reflect.enter(index) {
println(std.reflect.node_int())
std.reflect.leave()
}
index += 1
}
println(std.reflect.walk_depth())
std.reflect.walk_end()
}End the walk and drop the cursor.
How deep the cursor is; 0 when no walk is in progress.
What the node under the cursor is — one of the KIND_* values above.
How many children the node has: fields, elements, entries, payload slots. A struct reports its declared arity, so field names and child indices line up even where a value does not carry a field.
Returns the integer payload of the current reflection node.
Returns the float payload of the current reflection node.
Returns the Boolean payload of the current reflection node.
Returns the string payload of the current reflection node.
The declared name for a struct or enum, the primitive spelling otherwise.
The variant name of an enum node, or "" for anything else.
The i-th field name of a struct node, or "" for anything else.
index: Zero-based field position in the struct under the cursor.
Whether the i-th child exists — false past the end, and false for a struct field this value does not carry.
index: Zero-based child position to test for.
Descend into the i-th child. False (and no descent) when there is none.
index: Zero-based child position to descend into.
Descend into the i-th child and answer its kind, or -1 — without descending — when there is no such child. enter and node_kind in one question: a codec asks that pair for every field of every value, and the walk is a sequence of calls, so asking once is measurably cheaper than asking twice (overhaul plan E3).
index: Zero-based child position to descend into.
Descend into the i-th key of a dict node.
index: Zero-based entry position whose key to descend into.
Return to the parent.
Whether the declaration leaves this field out when it holds none.
type_name: The declared type name to look up.field: The field's declared name.
The name of a KIND_* value, for diagnostics.
kind: One of theKIND_*constants.
Begin building a value of T into dest, where the finished value is appended. Nothing is published until build_commit.
dest: Array the finished value is appended to on commit.
struct User { name: string, age: int, nickname: Optional<string> }
fn main() {
let users: [User] = []
std.reflect.build_begin<User>(users)
std.reflect.set_str(std.reflect.field_index<User>("name"), "moon")
std.reflect.set_int(std.reflect.field_index<User>("age"), 1)
std.reflect.set_none(std.reflect.field_index<User>("nickname"))
std.reflect.build_commit()
std.reflect.build_error().unwrap()
println(users[0].name)
std.reflect.build_value<User>()
std.reflect.set_value(std.reflect.field_index<User>("name"), "Tour")
std.reflect.set_int(std.reflect.field_index<User>("age"), 2)
std.reflect.set_none(std.reflect.field_index<User>("nickname"))
std.reflect.build_commit()
println(std.reflect.build_take<User>().unwrap().name)
}Begin building a value of T with no destination; build_take<T>() claims it once build_commit has finished it.
Claim the value a destination-less build finished.
Where name sits in T's declaration, or -1. Ask once per type; set by index in the loop.
name: The field's declared name inT.
Write an already-built value of any shape — a nested struct, an array, a dictionary, an enum — into the i-th field.
index: Zero-based field index in the declaration under construction.value: An already-built value of any shape.
Begin building the i-th field, which must itself be a declared struct. build_commit puts the finished value in that field and returns to the enclosing one — the enter/leave of the read cursor, writing.
index: Zero-based field index in the declaration under construction.
Write the i-th field. An Optional<T> field is wrapped for you, and a whole number reaching a float field converts.
index: Zero-based field index in the declaration under construction.value: The integer to write; a float field takes it converted.
Replaces the current reflection node with a float payload.
index: Zero-based field index in the declaration under construction.value: The float to write.
Replaces the current reflection node with a Boolean payload.
index: Zero-based field index in the declaration under construction.value: The boolean to write.
Replaces the current reflection node with a string payload.
index: Zero-based field index in the declaration under construction.value: The string to write.
Write none into the i-th field, which must be Optional<T>.
index: Zero-based field index in the declaration under construction. The field must beOptional<T>.
Finish the value under construction and publish it. A field that was never written is none where it can be and a failure where it cannot, and a failure ends the whole build rather than leaving the cursor half unwound.
Abandon every frame. Nothing built is published.
How many values are under construction; 0 when none is.
Begin one element of an array field, appended to that field's own array. The array is created on the first element and holds its elements flat, so they cost nothing each — and this is the only way to build an array of a struct type the caller cannot name, which is every array a decoder meets.
index: Zero-based index of the array field the element is appended to.
Write a payload-free variant of the field's declared enum, named by the wire's own spelling.
index: Zero-based field index in the declaration under construction.variant: The variant's own spelling, as the wire gives it.
How many fields the value under construction declares.
The declared name of the type under construction.
The i-th field's declared name.
index: Zero-based field index in the declaration under construction.
The i-th field's declared kind, with Optional unwrapped.
index: Zero-based field index in the declaration under construction.
Whether the i-th field is Optional<T>.
index: Zero-based field index in the declaration under construction.
The i-th field's declared type name, with Optional unwrapped, or "" where the type has no name of its own — an array, a dictionary, a tuple. Its kind says what it is and build_elem_type_name says what it holds.
index: Zero-based field index in the declaration under construction.
What one element of an array field holds, or one value of a dictionary field.
index: Zero-based index of the array or dictionary field to inspect.
The declared type name of an array field's element, or a dictionary field's value.
index: Zero-based index of the array or dictionary field to inspect.
The name of the mirrored value's type: a primitive spelling for the scalars, the declared name for a struct or an enum, and the resource kind for a native handle.
m: The mirror to name.
The names a value is keyed by: a struct's fields in declaration order, or a dictionary's string keys in insertion order. Every other kind has no keys and answers [].
m: The mirror to read; anything without keys answers[].
The value stored under key: a struct field by name, or a dictionary entry whose key is that string. none when the mirror has no such key.
m: The mirror to read.key: A struct field name, or a string dictionary key.
The element at position i, counting from zero: an Arr or Tup element, a struct's positional field, a dictionary's positional entry value, or an enum variant's payload slot. none when i is out of range.
m: The mirror to read.i: Zero-based position among the children.
Everything one level down: array/tuple elements, struct field values, dictionary entry values, or enum payload slots, in order. [] for a leaf.
m: The mirror to read; a leaf answers[].
Name/value pairs one level down: a struct's fields in declaration order, or a dictionary's string-keyed entries in insertion order. A dictionary entry whose key is not a string has no name and is left out; values still reaches it positionally.
m: The mirror to read; entries with no name are left out.
How many elements the mirror has one level down. Zero for every leaf, so length never has to be guarded by a kind test.
m: The mirror to measure; every leaf answers 0.
The integer a leaf holds, or none if it holds something else.
m: The mirror to read.
The float a leaf holds, or none if it holds something else.
m: The mirror to read.
The boolean a leaf holds, or none if it holds something else.
m: The mirror to read.
The string a leaf holds, or none if it holds something else.
m: The mirror to read.
Every leaf in the tree, paired with the path it sits at — the one-call answer to "enumerate keys and values recursively".
Paths use the same grammar the JSON codec's errors do: $ is the root, .name descends a struct field or a string-keyed dictionary entry, [i] descends an array/tuple element, an enum payload slot, or a dictionary entry with a non-string key. Some and Ok are transparent — their payload sits at the same path — so $.nickname names the string inside an Optional<string> exactly as it names a bare one.
m: The root of the tree to enumerate.
Does the tree contain a back-edge? mirror is total, so a value that contains itself comes back with a Ref in it rather than failing; this is the caller's way to notice.
m: The tree to scan for aRefback-edge.