pub enum ValueView<'a> {
Show 21 variants
Unit,
Bool(bool),
Int(i64),
Float(f64),
Duration(i64),
Str(&'a str),
Array(&'a [Value]),
Vector(Elements<'a>),
Map(Entries<'a>),
Set(Members<'a>),
Struct(StructView<'a>),
Enum(EnumView<'a>),
Closure(ClosureView<'a>),
HostModule(&'a str),
HostFn {
module: &'a str,
op: &'a str,
},
Resource(&'a ResourceHandle),
Type(&'a str),
Range(RangeBounds),
Task(TaskView<'a>),
TaskScope(TaskScopeView<'a>),
Shared(SharedView<'a>),
}Expand description
What kind of Cove value this is: the stable public classification, and the exhaustive match a host is allowed to write.
§Why this exists
Value’s variants are sealed (ADR 0028 decision 6), which takes away a
real safety property: a host that matched every variant got a compile
error when a new one arrived. Issue #196 raises exactly that objection.
This is the answer, and it is a better answer than the thing it replaces,
because today one enum carries two unrelated kinds of change and a host
cannot tell them apart. Moving a struct from a Box to an Rc (issue
#104) and “Cove has a new kind of value” arrive at a host as the same
compile error.
After this they are different events:
- a representation change is invisible — nothing here names an
Rc, aBox, a slot, a heap object or a tag, so how the runtime holds a value may move without a host noticing; - a language change is a compile error at every
match— a new kind of Cove value is a new variant here, and that is the right way round.
§It is exhaustive on purpose
This is deliberately not #[non_exhaustive], and that is the whole
point. A #[non_exhaustive] view would give back the syntax of an
exhaustive match and none of its value: every host would carry a _ arm,
and the compile error that a new kind of value should cause would never
happen anywhere.
The cost is real and is accepted: this is a second place every new kind of
Cove value must be added, and adding one is a breaking change for every
embedder. Forgetting is a compile error inside this crate, at
Value::view, which is the good case.
§What it promises
Each payload borrows from the value or copies out of it, and building one
allocates nothing — so every part named here must still be stored as the
thing it answers with. That is a promise about a materialized boundary
value and not about how the linear-memory backend holds one: ADR 0028
separates the two, and the parts that will actually move — slots, heap
objects, dynamic values — are not Value and never reach here.
A part whose storage sits behind a cell is answered as an opaque guard
rather than a borrow: Elements is the one that exists, and it is what
lets Vector be viewed at all.
There is no Dyn variant, because Value::view looks through the
wrapper like every reader beside it. Value::dyn_trait answers the
trait name for a host that wants it.
Variants§
Unit
()
Bool(bool)
Int(i64)
Float(f64)
Duration(i64)
A duration in nanoseconds, signed, exactly as
Value::as_duration_nanos answers it.
Str(&'a str)
Array(&'a [Value])
A fixed-length immutable sequence.
Vector(Elements<'a>)
A growable sequence, borrowed for as long as the view is held.
Map(Entries<'a>)
Set(Members<'a>)
Struct(StructView<'a>)
Enum(EnumView<'a>)
An enum value, including Option and Result.
Closure(ClosureView<'a>)
A callback. A host calls one back through
Reentry and never directly, since the body
belongs to the backend that made it.
HostModule(&'a str)
A bound host module such as console.
HostFn
A bound host operation such as console.println.
Fields
Resource(&'a ResourceHandle)
A handle to a resource the host owns. ADR 0013 decides that the handle is a name and that every field of it is part of that name, which is why the whole of it is the answer.
Type(&'a str)
A type used as a value, such as Vector in Vector.of(1, 2).
Range(RangeBounds)
An integer range, normalised to half-open bounds.
Task(TaskView<'a>)
A handle to a spawned task. Its value is reachable only through
await or through the scope settling it.
TaskScope(TaskScopeView<'a>)
The scope scope tasks { ... } binds.
Mutable state more than one task may reach. Its contents are reachable
only through lock, so there is nothing here to read.