// The pure protobuf wire runtime (proto3 binary format) every gRPC message
// serialises through: a `PbWriter` / `PbReader` pair over varints, zigzag-coded
// signed ints, `fixed32` / `fixed64`, length-delimited fields, packed repeated
// fields, and `map` entries. This writes one message touching every
// scalar kind, prints the tag stream, and reads each field straight back.
//
// moon run src/examples/05-protobuf-wire
///|
fn join_ints(xs : Array[Int32]) -> String {
let buf = StringBuilder()
for i, x in xs {
if i > 0 {
buf.write_string(", ")
}
buf.write_string(x.to_string())
}
buf.to_string()
}
///|
fn run() -> Unit raise {
let w = @moonrpc.PbWriter::new()
w.string_(1, "heke1228") // length-delimited
w.int32(2, -1) // a negative int32 varint spends the full ten octets
w.sint32(3, -233) // zigzag keeps a small magnitude short
w.uint64(4, 23333)
w.bool_(5, true)
w.enum_(6, 2)
w.fixed32(7, 66666)
w.fixed64(8, 23333)
w.bytes_(9, b"qwq")
w.packed_int32(10, [23, 42, 233]) // one length-delimited run of varints
w.map_string_string(11, "emm", "hhh") // a map entry
let body = w.to_bytes()
println("\{body.length()} octets: \{@base16.encode(body)}")
// Read the fields back in order, dispatching on the field number and wire type the
// tag carries. `WireType` is the low three bits of each tag.
let r = @moonrpc.PbReader::new(body)
while !r.eof() {
let (field, wire) = r.read_tag()
let shown = match field {
1 => r.read_string()
2 => r.read_int32().to_string()
3 => r.read_sint32().to_string()
4 => r.read_uint64().to_string()
5 => r.read_bool().to_string()
6 => r.read_int32().to_string()
7 => r.read_fixed32().to_string()
8 => r.read_fixed64().to_string()
9 => "\{r.read_bytes().length()} bytes"
10 => "[" + join_ints(r.read_packed_int32()) + "]"
11 => {
let (k, v) = r.read_map_string_string()
"\{k} => \{v}"
}
_ => {
r.skip(wire)
"(skipped)"
}
}
println(" field \{field} (\{wire}) = \{shown}")
}
}
///|
#coverage.skip
fn main {
run() catch {
e => println("error: \{e}")
}
}