|
| 1 | +# protobuf-pony |
| 2 | + |
| 3 | +Pure Pony protobuf runtime — wire codec, framing, scalar codecs, UTF-8 |
| 4 | +validation. The runtime that generated Pony code (emitted by |
| 5 | +[`protoc-gen-pony`](https://github.com/TrogonStack/protoc-gen)) calls into. |
| 6 | + |
| 7 | +## What's here |
| 8 | + |
| 9 | +- **`Varint`** — varint encode/decode + zigzag encode/decode (i32/i64). |
| 10 | +- **`Tag`** + **`TagCodec`** — protobuf field tag (field number + wire type). |
| 11 | +- **`WireType`** — typed union (`WireVarint | WireFixed64 | WireLenDelim | |
| 12 | + WireFixed32`); proto2 group wire types are deliberately omitted. |
| 13 | +- **`WireReader`** — cursor-style reader over `Array[U8] val`. Reads |
| 14 | + varints, tags, fixed-width fields, length-delimited bytes, UTF-8-validated |
| 15 | + strings; supports per-wire-type skip-unknown for forward-compat. |
| 16 | +- **`WireWriter`** — accumulating writer, returns an `Array[U8] iso^` on |
| 17 | + `done()`. Includes a `write_string_field(field_num, s)` helper that |
| 18 | + internalizes proto3's "skip empty strings" rule. |
| 19 | +- **`Scalar`** — paired encode/decode for all 12 protobuf scalar types |
| 20 | + (`bool`, `int32/64`, `uint32/64`, `sint32/64`, `fixed32/64`, |
| 21 | + `sfixed32/64`, `float`, `double`). Uses `F32/F64.from_bits/.bits` LLVM |
| 22 | + intrinsics for lossless float round-trip. |
| 23 | +- **`LE`** — little-endian byte conversion helpers, shift-based (no |
| 24 | + `Platform.bigendian()` branch needed since bit shifts produce LE bytes |
| 25 | + on any host). |
| 26 | +- **`WireError`** — typed-error union (`WireTruncated | WireOverflow | |
| 27 | + WireBadTag | WireInvalidUtf8`). |
| 28 | + |
| 29 | +## Install |
| 30 | + |
| 31 | +```json |
| 32 | +{ |
| 33 | + "deps": [ |
| 34 | + { |
| 35 | + "locator": "github.com/TrogonStack/protobuf-pony", |
| 36 | + "version": "0.1.0" |
| 37 | + } |
| 38 | + ] |
| 39 | +} |
| 40 | +``` |
| 41 | + |
| 42 | +Then in your Pony source: |
| 43 | + |
| 44 | +```pony |
| 45 | +use "protobuf" |
| 46 | +``` |
| 47 | + |
| 48 | +## Usage |
| 49 | + |
| 50 | +The typical caller is generated code from `protoc-gen-pony`. Sketch: |
| 51 | + |
| 52 | +```pony |
| 53 | +let writer = WireWriter |
| 54 | +writer.write_tag(Tag(1, WireVarint)) |
| 55 | +Scalar.write_int32(writer, 42) |
| 56 | +let bytes: Array[U8] val = recover val writer.done() end |
| 57 | +
|
| 58 | +let reader = WireReader(bytes) |
| 59 | +match reader.read_tag() |
| 60 | +| let t: Tag => /* dispatch on t.field_number, t.wire_type */ |
| 61 | +| let e: WireError => /* handle */ |
| 62 | +end |
| 63 | +``` |
| 64 | + |
| 65 | +Hand-writing decoders is supported but the expected workflow is to define |
| 66 | +your schemas in `.proto`, run `protoc-gen-pony`, and let the generated |
| 67 | +`<Msg>Codec` primitives call into this runtime. |
| 68 | + |
| 69 | +## Build + test |
| 70 | + |
| 71 | +Requires [Task](https://taskfile.dev), [corral](https://github.com/ponylang/corral), |
| 72 | +and `ponyc`. |
| 73 | + |
| 74 | +```bash |
| 75 | +corral fetch |
| 76 | +task test |
| 77 | +``` |
| 78 | + |
| 79 | +## License |
| 80 | + |
| 81 | +BSD-2-Clause. |
0 commit comments