[Upd] Docs
Some checks failed
CI / checks (push) Failing after 2m33s

This commit is contained in:
Alex 2026-08-19 12:37:22 +02:00
commit a6c4e56835
Signed by: alex
SSH key fingerprint: SHA256:D1+Ub8o0v4K5y1JNivW8IxEOelqLSvPmUzBbDIoZkRQ
14 changed files with 126 additions and 63 deletions

View file

@ -4,23 +4,28 @@ This file documents the connection and version negotiation logic.
## Registry
The `registry` module provides a multi-version `Registry` used by the host for version negotiation. Accessed through the `mtp` facade (requires the `host` feature):
The `registry` module provides a multi-version `Registry` used by the host for
version negotiation. Accessed through the `mtp` facade (requires the `host`
feature). In this repository, `Registry::builtin()` is generated from
[`example/type-maps.yaml`](../example/type-maps.yaml), which currently contains
protocol version 3.0 only. Downstream projects can register additional versions
in their own YAML configuration.
```rust
use mtp::codec::registry::Registry;
use mtp::codec::{Version, registry::Registry};
let registry = Registry::builtin(); // loads all TypeMaps from config
let registry = Registry::builtin(); // loads all TypeMaps from the build config
// Check if a version is supported
assert!(registry.supports(&Version(1, 0)));
assert!(registry.supports(&Version(3, 0)));
// Find highest mutual version for a client
let client_versions = &[Version(0, 0), Version(1, 0)];
let client_versions = &[Version(2, 0), Version(3, 0)];
let negotiated = registry.negotiate(client_versions);
assert_eq!(negotiated, Some(Version(1, 0)));
assert_eq!(negotiated, Some(Version(3, 0)));
// Look up a version's TypeMap
let tm = registry.get(&Version(2, 0)).unwrap();
let tm = registry.get(&Version(3, 0)).unwrap();
```
The `Registry::builtin()` constructor uses the `TypeMap::vX_Y()` methods generated from the config.
@ -54,9 +59,9 @@ let mut host = MTPHost::new(config).await?;
while let Some(conn) = host.accept().await? {
// conn.version is the negotiated version
// conn.codec is a VersionedCodec scoped to that version
// conn.sender / conn.receiver for raw CommunicationValue I/O
// conn.sender / conn.receive() for application CommunicationValue I/O
let msg = conn.receiver.receive().await?;
let msg = conn.receive().await?;
}
```
@ -94,29 +99,31 @@ The client's `PROTOCOL_VERSION` constant is set by `protocol_version` in `type-m
## Version Negotiation Flow
```
Client (v2.0) Host (v0.0, v1.0, v2.0)
Client (v3.0) Host (v3.0)
| |
| QUIC connect |
|----------------------->|
| |
| CommValue{ Ident. } |
| Version -> "2.0" |
| Version -> "3.0" |
| Id -> 8765 |
| (unsigned hello; auth |
| challenge follows) |
|----------------------->|
| | registry.negotiate(&[Version(2,0)])
| | -> Some(Version(2,0))
| | registry.negotiate(&[Version(3,0)])
| | -> Some(Version(3,0))
| |
| Response | selected v2.0 TypeMap
| Response | selected v3.0 TypeMap
|<-----------------------|
| Status, version |
| |
| subsequent messages |
| use v2.0 TypeMap |
| use v3.0 TypeMap |
```
If the client sends an unsupported version (e.g. v3.0 when the host only knows up to v2.0), `negotiate` returns `None` and the connection is closed.
If the client sends an unsupported version (for example, v2.0 to the current
repository builtin host), `negotiate` returns `None` and the connection is
closed.
## Protocol Ping and Pong