Rust
What Comline supports in Rust, as its conformance suites prove it. For how to use it, see the Rust guide. The states are explained in the overview.
Code generation
What the comline-rust generator emits
for each language feature, and the conformance fixtures that prove it.
Generator rust#1.85.0.
| Feature | What it covers | State | Proven by |
|---|---|---|---|
structs structs |
struct declarations |
✅ supported | primitives, optional_and_arrays, type_refs, protocol, shapes, cross_schema, import_alias, import_glob, nested_namespace, external_std, validators, validators_on_decode, format_json, format_msgpack |
enums enums |
enum declarations |
✅ supported | enum_basic |
optional fields optional-fields |
fields marked optional |
✅ supported | optional_and_arrays, type_refs, shapes, cross_schema, validators, validators_on_decode |
arrays arrays |
variable-length arrays, T[] |
✅ supported | optional_and_arrays, type_refs, shapes, cross_schema, validators, validators_on_decode |
fixed-length arrays fixed-arrays |
fixed-length arrays, T[N] |
✅ supported | shapes |
fixed arrays over 32 elements, nested large-fixed-arrays-nested |
a T[N] with N over 32 anywhere but a field's own, non-optional type: inside another array, optional, an alias, an argument or a return |
❌ unsupported: a fixed array over 32 elements renders only as a struct or error field's own, non-optional type (serde's derive stops at 32) | large_fixed_arrays_nested |
unions unions |
union(A B ...) types |
❌ unsupported: Rust has no anonymous sum type to render one as | unions |
type aliases type-aliases |
type Name = ... declarations |
✅ supported | validators, validators_on_decode |
constants constants |
const declarations |
✅ supported | constant, shapes, validators, validators_on_decode |
protocols protocols |
protocol declarations and their functions |
✅ supported | protocol, error_shapes, validators, validators_on_decode, framing_jsonrpc, handshake_none, connections, connections_async, connections_jsonrpc, format_json, format_msgpack |
errors errors |
error declarations |
✅ supported | protocol, error_shapes, format_json, format_msgpack |
functions that throw throws |
functions declared with ! Error |
✅ supported | protocol, error_shapes, format_json, format_msgpack |
validators validators |
@validators on fields and type aliases, checked in generated code |
✅ supported | validators, validators_on_decode |
imports between schemas imports |
use of another schema's declarations |
✅ supported | cross_schema, import_alias, import_glob, nested_namespace, external_std, validators, validators_on_decode |
nested namespaces nested-namespaces |
schemas in subdirectories (chat::admin) |
✅ supported | nested_namespace, external_std, validators, validators_on_decode |
lib mode lib-mode |
--mode lib: a buildable package, not bare source files |
✅ supported | nested_namespace, external_std |
external_std external-std |
[generate] external_std: std referenced as its own package |
✅ supported | external_std |
validate_on_decode validate-on-decode |
[generate] validate_on_decode: decoding runs the checks |
✅ supported | validators_on_decode |
JSON-RPC framing framing-jsonrpc |
@framing = "jsonrpc" (or as the package default) |
✅ supported | framing_jsonrpc, connections_jsonrpc |
no handshake handshake-none |
@handshake = "none" (or as the package default) |
✅ supported | handshake_none |
connections connections |
protocols on a connection, with calls in both directions: datagram@2 (the default), or @provider = Client / Multiple |
✅ supported | protocol, error_shapes, validators, validators_on_decode, handshake_none, connections, connections_async, connections_jsonrpc, format_json, format_msgpack |
async async |
[generate] async: connection protocols get async handlers and senders |
✅ supported | connections_async |
the packed@1 format format-packed |
wire.format = "packed@1", the default: fixed-width fields, no tags |
✅ supported | protocol, error_shapes, validators, validators_on_decode, handshake_none, connections, connections_async |
the json@1 format format-json |
wire.format = "json@1" |
✅ supported | format_json |
the msgpack@1 format format-msgpack |
wire.format = "msgpack@1" |
✅ supported | format_msgpack |
Runtime
What the comline-runtime runtime speaks on the wire, proven against the
shared wire corpus:
byte-exact examples of the handshake, the envelopes, each framing and each
wire format. The claims are in rust.json.
Runtime rust.
| Feature | What it covers | State | Proven by |
|---|---|---|---|
name hash name-hash |
FNV-1a 64 of a wire format or framing name, as the handshake carries it | ✅ supported | 8 cases |
handshake handshake |
the fixed 31-byte frame each side sends first: magic, version, IR hash, wire format, framing, capabilities | ✅ supported | 9 cases |
envelope envelope |
a response's outcome: ok with a payload, an error ordinal with its body, or a provider fault | ✅ supported | 8 cases |
datagram framing framing-datagram |
Comline's own binary framing of requests and responses | ✅ supported | 9 cases |
datagram@2 framing framing-datagram2 |
the datagram framing with a request/reply kind and a protocol number, for calls in both directions and several protocols on one connection | ✅ supported | 12 cases |
stream framing stream |
frames on a byte stream (TCP, a pipe): each behind a u32 little-endian length prefix, refused over the limit, by default 16 MiB (16777216 bytes) in every runtime | ✅ supported | 24 cases |
JSON-RPC framing framing-jsonrpc |
JSON-RPC 2.0 requests and responses, a fault as -32603 | ✅ supported | 19 cases |
JSON wire format format-json |
values as UTF-8 JSON: a struct as an object | ✅ supported | 46 cases |
MessagePack wire format format-msgpack |
values as MessagePack: a struct as an array | ✅ supported | 45 cases |
packed wire format format-packed |
values as packed@1: fixed-width fields back to back, varint lengths, no tags | ✅ supported | 59 cases |
Verification
The vectors above only cover cases someone wrote down. The Rust runtime is also checked on inputs nobody wrote, and it is the reference the other runtimes are compared against (see Verification).
Fuzzing and properties
- Seven
cargo-fuzztargets:decode_no_panic,packed_canonical,framing_decode,seed_vs_deriveandstream_split, and, for the C ABI,ffi_feedandffi_vs_core. - Property tests
(
proptest) over random types and values, run withcargo test. - CI runs each target for a minute on every pull request, and for ten minutes
nightly with the property tests at 100,000 cases. A nightly failure opens an
issue. Each finding becomes a
found-*vector, so every runtime checks it.
The nightly run publishes its results as rust.fuzz.json on the runtime's
reports branch
(format: the fuzz README).
The latest, fetched when this site was built:
From the run of 2026-10-29 at runtime commit 2033847, with rustc 1.101.0-nightly (92ffebece 2026-10-28) (run, rust.fuzz.json).
| Target | Seconds | Executions | Corpus | Findings |
|---|---|---|---|---|
decode_no_panic |
601 | 19,693,429 | 18,644 | 0 |
ffi_feed |
601 | 2,360,674 | 17,273 | 0 |
ffi_vs_core |
601 | 1,076,739 | 11,260 | 0 |
framing_decode |
601 | 30,633,604 | 8,620 | 0 |
packed_canonical |
601 | 7,586,124 | 1,791 | 0 |
seed_vs_derive |
601 | 22,287,096 | 26,351 | 0 |
stream_split |
601 | 164,956,253 | 42 | 0 |
Property tests: 8 properties at 100,000 cases each, all pass.
Divergences
The Rust runtime is the reference the others are compared against, so it has no divergence classes of its own: a difference is the other runtime's to explain.
Benchmarks
Instruction counts for the formats, framings, handshake and a connection step,
gated on every pull request against its base. Every push to main benches the
new head and publishes rust.bench.json on the runtime's
reports branch.
The latest, fetched when this site was built:
Measured at runtime commit 2033847 with rustc 1.98.0 (88d9e12ae 2026-08-18), in instructions executed (deterministic, so they compare exactly), from rust.bench.json.
All 162 benchmarks
| Benchmark | Instructions |
|---|---|
connection/step |
972 |
ffi/abi/encode-reply/datagram@2/message/16 |
462 |
ffi/abi/encode-reply/datagram@2/message/256 |
481 |
ffi/abi/encode-reply/datagram@2/message/4096 |
862 |
ffi/abi/encode-reply/datagram@2/message/65536 |
66,003 |
ffi/abi/encode-reply/datagram@2/stream/16 |
533 |
ffi/abi/encode-reply/datagram@2/stream/256 |
552 |
ffi/abi/encode-reply/datagram@2/stream/4096 |
933 |
ffi/abi/encode-reply/datagram@2/stream/65536 |
66,074 |
ffi/abi/encode-reply/jsonrpc@1/message/16 |
473 |
ffi/abi/encode-reply/jsonrpc@1/message/256 |
492 |
ffi/abi/encode-reply/jsonrpc@1/message/4096 |
873 |
ffi/abi/encode-reply/jsonrpc@1/message/65536 |
66,014 |
ffi/abi/encode-reply/jsonrpc@1/stream/16 |
544 |
ffi/abi/encode-reply/jsonrpc@1/stream/256 |
563 |
ffi/abi/encode-reply/jsonrpc@1/stream/4096 |
944 |
ffi/abi/encode-reply/jsonrpc@1/stream/65536 |
66,085 |
ffi/abi/encode-request/datagram@2/message/16 |
724 |
ffi/abi/encode-request/datagram@2/message/256 |
743 |
ffi/abi/encode-request/datagram@2/message/4096 |
1,124 |
ffi/abi/encode-request/datagram@2/message/65536 |
66,265 |
ffi/abi/encode-request/datagram@2/stream/16 |
796 |
ffi/abi/encode-request/datagram@2/stream/256 |
815 |
ffi/abi/encode-request/datagram@2/stream/4096 |
1,196 |
ffi/abi/encode-request/datagram@2/stream/65536 |
66,337 |
ffi/abi/encode-request/jsonrpc@1/message/16 |
906 |
ffi/abi/encode-request/jsonrpc@1/message/256 |
925 |
ffi/abi/encode-request/jsonrpc@1/message/4096 |
1,306 |
ffi/abi/encode-request/jsonrpc@1/message/65536 |
66,447 |
ffi/abi/encode-request/jsonrpc@1/stream/16 |
978 |
ffi/abi/encode-request/jsonrpc@1/stream/256 |
997 |
ffi/abi/encode-request/jsonrpc@1/stream/4096 |
1,378 |
ffi/abi/encode-request/jsonrpc@1/stream/65536 |
66,519 |
ffi/abi/feed/datagram@2/message/16 |
294 |
ffi/abi/feed/datagram@2/message/256 |
294 |
ffi/abi/feed/datagram@2/message/4096 |
294 |
ffi/abi/feed/datagram@2/message/65536 |
294 |
ffi/abi/feed/datagram@2/stream/16 |
299 |
ffi/abi/feed/datagram@2/stream/256 |
299 |
ffi/abi/feed/datagram@2/stream/4096 |
299 |
ffi/abi/feed/datagram@2/stream/65536 |
299 |
ffi/abi/feed/jsonrpc@1/message/16 |
1,703 |
ffi/abi/feed/jsonrpc@1/message/256 |
2,378 |
ffi/abi/feed/jsonrpc@1/message/4096 |
13,178 |
ffi/abi/feed/jsonrpc@1/message/65536 |
185,978 |
ffi/abi/feed/jsonrpc@1/stream/16 |
1,805 |
ffi/abi/feed/jsonrpc@1/stream/256 |
2,480 |
ffi/abi/feed/jsonrpc@1/stream/4096 |
13,280 |
ffi/abi/feed/jsonrpc@1/stream/65536 |
186,080 |
ffi/abi/handshake-check |
138 |
ffi/abi/handshake-check-out |
210 |
ffi/abi/handshake-encode |
772 |
ffi/abi/name-hash |
198 |
ffi/core/encode-reply/datagram@2/message/16 |
320 |
ffi/core/encode-reply/datagram@2/message/256 |
339 |
ffi/core/encode-reply/datagram@2/message/4096 |
720 |
ffi/core/encode-reply/datagram@2/message/65536 |
65,813 |
ffi/core/encode-reply/datagram@2/stream/16 |
392 |
ffi/core/encode-reply/datagram@2/stream/256 |
411 |
ffi/core/encode-reply/datagram@2/stream/4096 |
792 |
ffi/core/encode-reply/datagram@2/stream/65536 |
65,885 |
ffi/core/encode-reply/jsonrpc@1/message/16 |
331 |
ffi/core/encode-reply/jsonrpc@1/message/256 |
350 |
ffi/core/encode-reply/jsonrpc@1/message/4096 |
731 |
ffi/core/encode-reply/jsonrpc@1/message/65536 |
65,824 |
ffi/core/encode-reply/jsonrpc@1/stream/16 |
403 |
ffi/core/encode-reply/jsonrpc@1/stream/256 |
422 |
ffi/core/encode-reply/jsonrpc@1/stream/4096 |
803 |
ffi/core/encode-reply/jsonrpc@1/stream/65536 |
65,896 |
ffi/core/encode-request/datagram@2/message/16 |
336 |
ffi/core/encode-request/datagram@2/message/256 |
355 |
ffi/core/encode-request/datagram@2/message/4096 |
736 |
ffi/core/encode-request/datagram@2/message/65536 |
65,829 |
ffi/core/encode-request/datagram@2/stream/16 |
408 |
ffi/core/encode-request/datagram@2/stream/256 |
427 |
ffi/core/encode-request/datagram@2/stream/4096 |
808 |
ffi/core/encode-request/datagram@2/stream/65536 |
65,901 |
ffi/core/encode-request/jsonrpc@1/message/16 |
518 |
ffi/core/encode-request/jsonrpc@1/message/256 |
537 |
ffi/core/encode-request/jsonrpc@1/message/4096 |
918 |
ffi/core/encode-request/jsonrpc@1/message/65536 |
66,011 |
ffi/core/encode-request/jsonrpc@1/stream/16 |
590 |
ffi/core/encode-request/jsonrpc@1/stream/256 |
609 |
ffi/core/encode-request/jsonrpc@1/stream/4096 |
990 |
ffi/core/encode-request/jsonrpc@1/stream/65536 |
66,083 |
ffi/core/feed/datagram@2/message/16 |
141 |
ffi/core/feed/datagram@2/message/256 |
141 |
ffi/core/feed/datagram@2/message/4096 |
141 |
ffi/core/feed/datagram@2/message/65536 |
141 |
ffi/core/feed/datagram@2/stream/16 |
150 |
ffi/core/feed/datagram@2/stream/256 |
150 |
ffi/core/feed/datagram@2/stream/4096 |
150 |
ffi/core/feed/datagram@2/stream/65536 |
150 |
ffi/core/feed/jsonrpc@1/message/16 |
1,550 |
ffi/core/feed/jsonrpc@1/message/256 |
2,225 |
ffi/core/feed/jsonrpc@1/message/4096 |
13,025 |
ffi/core/feed/jsonrpc@1/message/65536 |
185,825 |
ffi/core/feed/jsonrpc@1/stream/16 |
1,656 |
ffi/core/feed/jsonrpc@1/stream/256 |
2,331 |
ffi/core/feed/jsonrpc@1/stream/4096 |
13,131 |
ffi/core/feed/jsonrpc@1/stream/65536 |
185,931 |
ffi/core/handshake-check |
100 |
ffi/core/handshake-check-out |
130 |
ffi/core/handshake-encode |
437 |
ffi/core/name-hash |
49 |
format/decode/enum-heavy/json@1 |
13,246 |
format/decode/enum-heavy/msgpack@1 |
7,215 |
format/decode/enum-heavy/packed@1 |
2,187 |
format/decode/large-array/json@1 |
1,888,552 |
format/decode/large-array/msgpack@1 |
327,250 |
format/decode/large-array/packed@1 |
37,342 |
format/decode/nested/json@1 |
12,999 |
format/decode/nested/msgpack@1 |
3,579 |
format/decode/nested/packed@1 |
2,490 |
format/decode/small-scalar/json@1 |
2,451 |
format/decode/small-scalar/msgpack@1 |
453 |
format/decode/small-scalar/packed@1 |
93 |
format/decode/string-heavy/json@1 |
10,551 |
format/decode/string-heavy/msgpack@1 |
4,052 |
format/decode/string-heavy/packed@1 |
3,881 |
format/encode/enum-heavy/json@1 |
18,340 |
format/encode/enum-heavy/msgpack@1 |
8,985 |
format/encode/enum-heavy/packed@1 |
3,102 |
format/encode/large-array/json@1 |
3,124,720 |
format/encode/large-array/msgpack@1 |
1,209,687 |
format/encode/large-array/packed@1 |
239,200 |
format/encode/nested/json@1 |
19,981 |
format/encode/nested/msgpack@1 |
5,135 |
format/encode/nested/packed@1 |
2,075 |
format/encode/small-scalar/json@1 |
3,954 |
format/encode/small-scalar/msgpack@1 |
1,198 |
format/encode/small-scalar/packed@1 |
328 |
format/encode/string-heavy/json@1 |
11,748 |
format/encode/string-heavy/msgpack@1 |
3,809 |
format/encode/string-heavy/packed@1 |
1,670 |
framing/decode/datagram@1/16 |
54 |
framing/decode/datagram@1/256 |
54 |
framing/decode/datagram@1/4096 |
54 |
framing/decode/datagram@1/65536 |
54 |
framing/decode/datagram@2/16 |
98 |
framing/decode/datagram@2/256 |
98 |
framing/decode/datagram@2/4096 |
98 |
framing/decode/datagram@2/65536 |
98 |
framing/decode/jsonrpc@1/16 |
1,471 |
framing/decode/jsonrpc@1/256 |
2,146 |
framing/decode/jsonrpc@1/4096 |
12,946 |
framing/decode/jsonrpc@1/65536 |
185,746 |
framing/encode/datagram@1/16 |
190 |
framing/encode/datagram@1/256 |
209 |
framing/encode/datagram@1/4096 |
590 |
framing/encode/datagram@1/65536 |
65,683 |
framing/encode/datagram@2/16 |
314 |
framing/encode/datagram@2/256 |
333 |
framing/encode/datagram@2/4096 |
714 |
framing/encode/datagram@2/65536 |
65,807 |
framing/encode/jsonrpc@1/16 |
317 |
framing/encode/jsonrpc@1/256 |
336 |
framing/encode/jsonrpc@1/4096 |
717 |
framing/encode/jsonrpc@1/65536 |
65,810 |
handshake/check |
19 |
handshake/decode |
46 |
handshake/encode |
336 |