Skip to content

feat(rust): @framing selector for a protocol's connect/serve helpers - #9

Merged
Kinflou merged 1 commit into
mainfrom
feat/framing-selector
Sep 1, 2026
Merged

feat(rust): @framing selector for a protocol's connect/serve helpers#9
Kinflou merged 1 commit into
mainfrom
feat/framing-selector

Conversation

@Kinflou

@Kinflou Kinflou commented Sep 1, 2026

Copy link
Copy Markdown
Member

What

Makes wire framing reachable from a schema. A protocol declares it with an annotation:

@framing = "jsonrpc"
protocol Rpc {
    function now() -> u32;
}

The Rust generator reads @framing off the frozen Protocol.parameters and, for a non-datagram pick, emits the JSON-RPC stack instead of the hard-wired datagram one:

generated item datagram (default, unchanged) @framing = "jsonrpc"
<Proto>Client newtype Client<T, W> Client<T, W, comline_runtime::framing::JsonRpcFraming>
connect() Client::connect(..) Client::connect_with_framing(.., framing, ..)
<Proto>Dispatcher::serve() Server::new(..) Server::with_framing(.., framing)
Handshake framing field FRAMING_DATAGRAM framing.name()
contract imports as before + Framing, - FRAMING_DATAGRAM when no protocol in the file needs it

Recognised values: jsonrpc, json-rpc, jsonrpc-2.0. Anything absent or unrecognised keeps the datagram default byte-for-byte — the conformance goldens don't move.

Why

The handshake, Framing trait, JsonRpcFraming impl, and *_with_framing constructors all already exist in the runtime; nothing selected them. This is the last piece: a schema-level switch so the generated connect / serve helpers aren't pinned to datagram.

No RUNTIME_REV bump — the runtime side is already landed.

Tests

  • generate.rs::framing_annotation_selects_jsonrpc_for_the_connect_and_serve_helpers — string-checks the emitted JSON-RPC stack and the absence of the datagram path.
  • compiles.rs — a second schema carrying a @framing = "jsonrpc" protocol is generated and cargo build-ed against the real comline-runtime next to the datagram one.
  • Existing code_mode_generates_enum_and_protocol (asserts the exact datagram imports + Server::new + Client::connect) still passes unchanged.

A protocol can now declare its wire framing with an annotation:

    @framing = "jsonrpc"
    protocol Rpc { function now() -> u32; }

The generator reads it off the frozen Protocol.parameters and, for a
non-datagram pick, emits the JSON-RPC stack instead of the hard-wired
datagram one:

  - <Proto>Client wraps Client<T, W, comline_runtime::framing::JsonRpcFraming>
  - connect() calls Client::connect_with_framing(..)
  - <Proto>Dispatcher::serve() calls Server::with_framing(..)
  - the Handshake carries framing.name() rather than FRAMING_DATAGRAM
  - the Framing trait is added to the generated import list; FRAMING_DATAGRAM
    is dropped when no protocol in the file uses it

Absent or unrecognised @framing keeps the datagram default, byte-for-byte
(the conformance goldens are unchanged). No runtime rev bump — the runtime
already ships JsonRpcFraming + the *_with_framing constructors.

tests:
  - generate.rs: @framing = "jsonrpc" emits the JsonRpcFraming stack
  - compiles.rs: a second schema with a @framing = "jsonrpc" protocol is
    compiled against the real runtime alongside the datagram one
@Kinflou

Kinflou commented Sep 1, 2026

Copy link
Copy Markdown
Member Author

Framing should likely be at a project's settings level such as comline.toml, this is just for testing

@Kinflou
Kinflou merged commit c6c27f8 into main Sep 1, 2026
2 checks passed
@Kinflou
Kinflou deleted the feat/framing-selector branch September 1, 2026 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant