std/encoding/values

std/encoding/src/values.trb

A value without its type: EncodedValue, the Values encoder that builds one, and the ValueDecoder that reads a typed value back out of one.

EncodedValue is what a program holds where it has left the type behind - a quotation's captures, a field default in a schema, the text rendered shows. It is one format among many, an encoder that writes into memory, and nothing goes through it unless a program asks for a value without its type.

ValueDecoder is the one Decoder every buffering format shares: a text format with unordered fields parses into an EncodedValue and hands it over, instead of writing a state machine of its own.

type EncodedValue

type EncodedValue with Show

Any Encode value, held without its type. Every scalar of the vocabulary has a case, so nothing is lost: a narrow number is already widened, and a Decimal stays exact.

Examples

type Point {
  x: Int
  y: Int
}

print EncodedValue.of(Point(1, 2))

Related

  • rendered - the same, as the text a message shows.

case Nothing

case Nothing

An absent value: what None writes.

case Bool

case Bool(value: Bool)

A truth value.

case Int

case Int(value: Int64)

A whole number, widened to 64 bits.

case Unsigned

case Unsigned(value: UInt64)

A whole number that may not fit into an Int64.

case Float

case Float(value: Float64)

A floating point number.

case Exact

case Exact(value: Decimal)

An exact decimal number, with every digit and its scale: 19.90 stays 19.90.

case String

case String(value: String)

A text.

case Bytes

case Bytes(value: Bytes)

Raw bytes.

case Sequence

case Sequence(items: List<Self>)

The items of a sequence, in order.

case Mapping

case Mapping(entries: List<Self>)

The entries of a map, flat: a key, then its value, then the next key.

case Record

case Record(typeName: String, fields: List<EncodedField>)

A record, with the qualified name of its type and its fields in declaration order.

case Variant

case Variant(typeName: String, name: String, fields: List<EncodedField>)

One case of a type with cases, with the fields of that case.

fn of

static fn of<Value: Encode>(value: Value, privateFields: Bool = false): Self

EncodedValue.of(user): the value, written by Values. With privateFields, a private field with a default is written as well, so the value is the whole value and not only its data (Encoder.writesPrivateFields).

fn show

fn show(): String

Price(amount: 19.99, currency: "EUR"): the shape the generated Show of the type has, too.

fn plain

fn plain(): String

The unquoted text of a scalar, which is what a SQL default and a --help line want.

extend EncodedValue with Encode

extend EncodedValue with Encode

An EncodedValue writes itself into any encoder, which is what makes it useful: a captured value can be bound as a SQL parameter, and a document nobody has a type for can be written out again.

fn encode

fn encode<Target: Encoder>(var target: Target)

type EncodedField

type EncodedField

One named field of an EncodedValue.Record or EncodedValue.Variant.

field name

name: String

The field's name, as the type declares it.

field value

value: EncodedValue

What the field holds.

fn show

fn show(): String

name: value, the way a record shows its fields.

fn rendered

fn rendered<Value: Encode>(value: Value): String

Any Encode value as readable text, for messages and debugging: User(name: "Ada", tags: ["math"]). It is EncodedValue.of and then EncodedValue.show.

Examples

print rendered([1, 2, 3])

type Values

type Values with Encoder

An Encoder that builds an EncodedValue. It is a format like any other, and the only one without bytes.

A record that announced no field and holds one value is a wrapper, and it becomes that value.

field privateFields

privateFields: Bool = false

Whether a private field with a default is written as well (Encoder.writesPrivateFields).

fn writesPrivateFields

fn writesPrivateFields(): Bool

The privateFields option: whether the whole value is written, private fields with a default included.

fn result

fn result(): EncodedValue

What was written. Nothing when nothing was.

fn nothing

var fn nothing()

Completes the current value as EncodedValue.Nothing.

fn bool

var fn bool(value: Bool)

Completes the current value as an EncodedValue.Bool.

fn int

var fn int(value: Int64)

Completes the current value as an EncodedValue.Int.

fn unsigned

var fn unsigned(value: UInt64)

Completes the current value as an EncodedValue.Unsigned.

fn float

var fn float(value: Float64)

Completes the current value as an EncodedValue.Float.

fn decimal

var fn decimal(value: Decimal)

Completes the current value as an EncodedValue.Exact.

fn string

var fn string(value: String)

Completes the current value as an EncodedValue.String.

fn bytes

var fn bytes(value: Bytes)

Completes the current value as EncodedValue.Bytes.

fn sequence

var fn sequence(length: Int?)

Opens a sequence; the length is ignored, the items written until Values.finish are what counts.

fn map

var fn map(length: Int?)

Opens a map; the length is ignored, the keys and values written until Values.finish are its entries.

fn record

var fn record(typeName: String)

Opens a record named typeName; its fields are the ones announced with Values.field until Values.finish.

fn variant

var fn variant(typeName: String, name: String)

Opens the case name of the variant typeName; its fields follow as a record's do.

fn field

var fn field(name: String)

Names the field whose value is written next. It does nothing when no record is open.

fn finish

var fn finish()

Closes the innermost open sequence, map, record or variant and completes it as the matching EncodedValue. A record without a field that holds one value completes as that value. It does nothing when none is open.

type ValueDecoder

type ValueDecoder with Decoder

A Decoder over an EncodedValue. A format whose input has to be buffered anyway - a text format with unordered fields, a tabular row, a command line - parses into an EncodedValue and hands it to this decoder.

lenient is what a format without numbers needs: XML, CSV and a command line have only text, so int() and float() parse what they are given. naming is how the format spelled the field names, and strict reports a field of the input that no type asked for. All three are options of the format, decided once, and never a question a type asks.

An exact number is read from an EncodedValue.Exact, and from a whole number or a float by its text. A text is no number to decimal(), except under lenient, for a map key, and where exactAsText is set: a format without a decimal type, such as TOML, writes a Decimal as a string and reads it back from one.

A record's fields are also a map with text keys, and a text key is read as a number or a truth value where the key type asks for one: JSON writes every key of an object as a text.

Examples

var source = ValueDecoder.of EncodedValue.Sequence([EncodedValue.Int(1), EncodedValue.Int(2)])
print List<Int>.decode(source)

fn of

static fn of(value: EncodedValue, lenient: Bool = false, naming: Naming = Naming.Unchanged, strict: Bool = false, privateFields: Bool = false, flagsAsNames: Bool = false, exactAsText: Bool = false): Self

A decoder that reads value, with the options of the format that parsed it. privateFields reads back what EncodedValue.of(value, privateFields: true) wrote: the whole value. flagsAsNames reads a Flags from the list of its case names, which is how a format with that option wrote it. exactAsText reads a Decimal from a text, which is how a format without a decimal type wrote it.

fn readsPrivateFields

fn readsPrivateFields(): Bool

The privateFields option: whether fields that are no constructor parameter are read where the value has them.

fn flagsAsNames

fn flagsAsNames(): Bool

The flagsAsNames option: whether a Flags is read from the list of its case names and not from its mask.

fn nothing

var fn nothing(): Bool

Takes the next value and answers true if it is EncodedValue.Nothing; any other value stays unread.

fn bool

var fn bool(): Result<Bool, DecodeError>

Reads an EncodedValue.Bool; the text true or false is accepted under lenient and for a map key.

fn int

var fn int(): Result<Int64, DecodeError>

Reads an integer: an EncodedValue.Int, an EncodedValue.Unsigned that fits, a whole EncodedValue.Float or a whole EncodedValue.Exact in range. A text is parsed where lenient is set or a map key is read.

fn unsigned

var fn unsigned(): Result<UInt64, DecodeError>

Reads a count: an EncodedValue.Unsigned, or an EncodedValue.Int that is not negative. A text is parsed where lenient is set or a map key is read.

fn float

var fn float(): Result<Float64, DecodeError>

Reads a number: an EncodedValue.Float, an EncodedValue.Int widened, or an EncodedValue.Exact rounded to the nearest Float64. A text is parsed under lenient.

fn decimal

var fn decimal(): Result<Decimal, DecodeError>

Reads an exact number: an EncodedValue.Exact as it is, an integer or a float by its text. A text is parsed where lenient or exactAsText is set or a map key is read, and refused otherwise, as every number field refuses one.

fn string

var fn string(): Result<String, DecodeError>

Reads an EncodedValue.String; under lenient, any other value is read as its plain text.

fn bytes

var fn bytes(): Result<Bytes, DecodeError>

Bytes, or a sequence of numbers that each fit into a byte: the way a text format writes them.

fn sequence

var fn sequence(): Result<Int?, DecodeError>

Opens an EncodedValue.Sequence and answers its length. Under lenient a single value is a sequence of one and a EncodedValue.Nothing an empty one.

fn map

var fn map(): Result<Int?, DecodeError>

A mapping, or a record read as a map from its field names: the only map a text format has is an object.

fn hasNext

var fn hasNext(): Result<Bool, DecodeError>

Whether the open sequence or map has an item left; false when nothing is open.

fn record

var fn record(typeName: String): Result<Void, DecodeError>

The name is not compared: a tabular row and a JSON object do not carry one, and the type asked for this one.

A bare value where a record was asked for is a wrapper: it comes back as the one thing the record holds, which is exactly what the writing side put there.

fn variant

var fn variant(typeName: String): Result<String, DecodeError>

Opens a variant and answers the name of its case. The value is an EncodedValue.Variant, a bare text for a case without fields, or a record of one field named after the case, as a text format writes it. The type name is not compared.

fn field

var fn field(name: String): Result<Bool, DecodeError>

Positions on the field name, spelled as the format's naming spells it, and answers whether the open record has it. It fails when no record is open or the open record is a wrapper around a bare value.

fn finish

var fn finish(): Result<Void, DecodeError>

Closes the innermost open sequence, map, record or variant. It fails when nothing is open, and under strict when the closed record has a field that no field call read.