OxL Справочник OxL
РусскийEnglish

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 field field(tag, name) and its value, endMessage(); an absent optional field is skipped, a none element of a list is writeNull();
  • List, Set, arrays: beginList(len) the elements endList(); 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: writeI64 nanoseconds; Date: writeI64 days; Time: writeStr (RFC 3339);
  • finish() returns the bytes of the document (called after the last event).

Example:

oxl✓ проверяется в CI
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 }))
}
Вывод
<Point 1:x=i1 2:y=i-2>
pub(api) interface Encoder

С версии. 1.0.0-beta

Методы

isJson() -> bool
Whether 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() -> bytes
The bytes of the finished document; called once after the last event.

Определено в: std/ser/ser.oxl:426

См. также