interface Encoder
The writer of a format (§9.5): handed to Codec.encode, and the sink of a user format (level 3). encode walks the value
and reports what it finds as calls of these methods; all of them have defaults (they do nothing; finish returns empty
bytes), so a format implements only what it needs. Written as a type (w: &var Encoder) it means dyn Encoder.
- a message (data, tuple, enum with fields, union):
beginMessage(typeName), per fieldfield(tag, name)and its value,endMessage(); an absent optional field is skipped, anoneelement of a list iswriteNull(); List,Set, arrays:beginList(len)the elementsendList();Map:beginMap(len)key value ...endMap();- integers up to 64 bits:
writeI64(signed) /writeU64;char, enum numbers of an open enum:writeU64; 128-bit integers:writeBytes(16 bytes, little-endian); floats:writeF64; enum without fields:writeStr(variant);Duration,LocalDateTime:writeI64nanoseconds;Date:writeI64days;Time:writeStr(RFC 3339); finish()returns the bytes of the document (called after the last event).
Example:
use std.ser { encode, bytesOf, Format, Encoder, Decoder }
// a debugging text format that prints every event it receives
data Log { out: String }
impl Encoder for Log {
var fn beginMessage(name: str) { out.push("<{name}") }
var fn endMessage() { out.push(">") }
var fn field(tag: u32, name: str) { out.push(" {tag}:{name}=") }
var fn writeI64(v: i64) { out.push("i{v}") }
var fn writeU64(v: u64) { out.push("u{v}") }
var fn writeF64(v: f64) { out.push("f{v}") }
var fn writeBool(v: bool) { out.push(if v { "T" } else { "F" }) }
var fn writeStr(v: str) { out.push("'{v}'") }
var fn writeBytes(v: bytes) { out.push("b{v.len()}") }
var fn writeNull() { out.push("null") }
var fn beginList(len: usize) { out.push("[{len}:") }
var fn endList() { out.push("]") }
var fn beginMap(len: usize) { out.push("{{{len}:") }
var fn endMap() { out.push("}}") }
var fn finish() -> bytes {
let text = out.freeze()
bytesOf(&text)
}
}
data NoDecoder {}
impl Decoder for NoDecoder {}
data LogFormat {}
impl Format for LogFormat {
fn name() -> str => "log"
fn encoder() -> Encoder => Log{ out: String.new() }
fn decoder(input: bytes) -> Decoder => NoDecoder{}
}
fn show<T: Serializable>(x: T) -> str {
comptime { std.ser.register(LogFormat) }
match encode(x, LogFormat) {
bytes b => {
match Utf8.decode(b) {
str t => t
DecodeError _ => "?"
}
}
EncodeError _ => "encode error"
}
}
data Point { x: i32; y: i32 }
fn main() io {
print(show(Point{ x: 1, y: -2 }))
}Output
<Point 1:x=i1 2:y=i-2>
pub(api) interface EncoderSince. 1.0.0-beta
Methods
isJson | () -> boolWhether the format is JSON (codecs may then write a different representation |
beginMessage | (name: str)Starts a message (a data, tuple, enum with fields or union) named name; the fields follow as field(tag, name) and a value each. |
endMessage | ()Ends the message that beginMessage started. |
field | (tag: u32, name: str)Starts the field tag (binary) / name (text formats) of the current message. |
writeI64 | (v: i64)Writes a signed integer of up to 64 bits. |
writeU64 | (v: u64)Writes an unsigned integer of up to 64 bits (also char and the numbers of an open enum). |
writeF64 | (v: f64)Writes a floating point number. |
writeBool | (v: bool)Writes a boolean. |
writeStr | (v: str)Writes a text (also the variant name of an enum without fields). |
writeBytes | (v: bytes)Writes a byte string (also 128-bit integers |
writeNull | ()Writes an absent element of a list (an absent optional field is skipped instead). |
beginList | (len: usize)Starts a list, set or array of len elements. |
endList | ()Ends the list that beginList started. |
beginMap | (len: usize)Starts a map of len entries; keys and values follow alternately. |
endMap | ()Ends the map that beginMap started. |
finish | () -> bytesThe bytes of the finished document; called once after the last event. |
Defined in: std/ser/ser.oxl:426