docs: missing_docs sweep — 0 warnings + deny gate + publish-prep decisions (HY-02, HY-04, HY-11)
- document every public-API item across 18 files (openapi_spec model, HttpAuthScheme/HttpServiceConfig, HttpClientBuildError + SharedHttpClient accessors, RetryAfterMiddleware, GatewayDispatch, gateway error mapping, CallRequest/SchemaQuery/SubscribeStream, HttpAdapter + ALPNs + builders, decoy/healthz/state, WsSessions/WsPumps, from_openapi/from_jsonschema/from_mcp/from_wss/to_mcp, lib.rs module docs) - enforcement: #![deny(missing_docs)] at crate root — stronger than CI rustdocflags (every build incl. cfg(test), where rustdoc misses the test-support module docs) - HY-10 (opportunistic): all 8 docs.rs/alkhttp placeholder ADR links + the one relative ../docs link converted to plain text; the 10 pre-existing private/redundant intra-doc-link warnings fixed — RUSTDOCFLAGS="-D warnings" cargo doc is fully clean - HY-11 decision: docs/ + tasks/ excluded from the published package (contributor-facing design/process material; ADR references degrade to plain text uniformly). cargo publish --dry-run: 38 files, ~889 KiB, zero docs/ or tasks/ entries - HY-04 decision: keep + document — frame_channel0_chunk's unwrap is on serializing the acyclic EventEnvelope (unreachable failure); # Panics on it and the adjacent WsClient senders state the contract Verified: cargo test (299 + 5 TLS), --all-features (370 + suites), --no-default-features (299), clippy --all-targets -D warnings (default + all-features), fmt --check, cargo doc -D warnings clean, cargo publish --dry-run --allow-dirty clean. Tasks: review-001-missing-docs-sweep (final pending task; 42/42)
This commit is contained in:
@@ -38,8 +38,8 @@
|
||||
//! bytes drain (the mux's EOF sentinels ride the same queue).
|
||||
//!
|
||||
//! Shared with the `from_wss` consumer path (ADR-070): one
|
||||
//! implementation, both directions ([`WsFraming`] + the generic
|
||||
//! [`run_read_pump`] / [`run_write_pump`] instantiated once per socket
|
||||
//! implementation, both directions (`WsFraming` + the generic
|
||||
//! `run_read_pump` / `run_write_pump` instantiated once per socket
|
||||
//! flavor — WS-11/COV-03).
|
||||
|
||||
use std::{
|
||||
@@ -402,6 +402,8 @@ pub struct WsPumps {
|
||||
}
|
||||
|
||||
impl WsPumps {
|
||||
/// Abort both pump tasks (forced session teardown; the remote sees
|
||||
/// an abrupt close, not a graceful one).
|
||||
pub fn abort(&self) {
|
||||
self.read_task.abort();
|
||||
self.write_task.abort();
|
||||
@@ -454,8 +456,7 @@ impl WsFraming for AxumFraming {
|
||||
}
|
||||
|
||||
/// Split a `WebSocket` into the byte stream + the pump tasks with the
|
||||
/// default idle-read timeout
|
||||
/// ([`DEFAULT_WS_IDLE_TIMEOUT`](crate::websocket::DEFAULT_WS_IDLE_TIMEOUT)).
|
||||
/// default idle-read timeout (`crate::websocket::DEFAULT_WS_IDLE_TIMEOUT`).
|
||||
/// See [`split_ws_to_bytes_idle`] for the configurable form.
|
||||
pub fn split_ws_to_bytes(socket: WebSocket) -> (WsByteStream, WsPumps) {
|
||||
split_ws_to_bytes_idle(socket, Some(DEFAULT_WS_IDLE_TIMEOUT))
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
//! WebSocket subsystem: the browser bidirectional path
|
||||
//! ([ADR-067](../docs/architecture/decisions/067-websocket-carries-channels.md)).
|
||||
//! (ADR-067, `docs/architecture/decisions`).
|
||||
//!
|
||||
//! A WS session carries the **channels protocol**: the 8-byte chunk
|
||||
//! header multiplexes N logical channels over the WS binary message
|
||||
//! stream; channel 0 is pre-negotiated as `alk/call` and dispatched by
|
||||
//! the shared `Dispatcher`. The WS↔byte-stream adapter
|
||||
//! ([`byte_adapter`]) is the single seam between axum's WS and
|
||||
//! the shared `Dispatcher`. The WS↔byte-stream adapter (`byte_adapter`)
|
||||
//! is the single seam between axum's WS and
|
||||
//! alkcall's byte-oriented channels machinery — shared with the
|
||||
//! `from_wss` consumer path ([ADR-070]).
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@ impl axum::extract::FromRef<Arc<OperationRegistry>> for SessionState {
|
||||
}
|
||||
|
||||
impl WsSessions {
|
||||
/// A fresh, empty session registry.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
@@ -173,6 +174,7 @@ impl WsSessions {
|
||||
self.sessions.lock().len()
|
||||
}
|
||||
|
||||
/// Whether no sessions are tracked.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.sessions.lock().is_empty()
|
||||
}
|
||||
@@ -400,6 +402,17 @@ pub mod test_support {
|
||||
/// Frame one `EventEnvelope` as a channel-0 chunk (8-byte chunk
|
||||
/// header + 4-byte length prefix + JSON body) — the client-side
|
||||
/// framing channel 0 uses over any transport.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics only if `serde_json` cannot serialize the envelope —
|
||||
/// unreachable for the acyclic wire type (no non-string map keys,
|
||||
/// no untagged ambiguities), which is why this returns `Vec<u8>`
|
||||
/// rather than `Result`: a test helper returning `Result` for an
|
||||
/// impossible case is worse ergonomics than a documented panic
|
||||
/// (review 001 HY-04, kept-as-is decision — the item ships behind
|
||||
/// the opt-in `test-support` feature, the crate's documented
|
||||
/// exception to no-panics-in-library-code).
|
||||
pub fn frame_channel0_chunk(envelope: &EventEnvelope) -> Vec<u8> {
|
||||
let body = serde_json::to_vec(envelope).unwrap();
|
||||
let mut out = Vec::with_capacity(8 + 4 + body.len());
|
||||
@@ -418,14 +431,19 @@ pub mod test_support {
|
||||
}
|
||||
|
||||
impl ChunkAssembler {
|
||||
/// A fresh, empty assembler.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Append raw bytes to the assembly buffer.
|
||||
pub fn push(&mut self, bytes: &[u8]) {
|
||||
self.buf.extend_from_slice(bytes);
|
||||
}
|
||||
|
||||
/// Extract the next complete `(channel_id, payload)` chunk, if
|
||||
/// a full one is buffered (8-byte header + declared payload
|
||||
/// length).
|
||||
pub fn next_chunk(&mut self) -> Option<(u32, Vec<u8>)> {
|
||||
if self.buf.len() < 8 {
|
||||
return None;
|
||||
@@ -454,14 +472,19 @@ pub mod test_support {
|
||||
}
|
||||
|
||||
impl FrameAssembler {
|
||||
/// A fresh, empty assembler.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Append raw bytes to the assembly buffer.
|
||||
pub fn push(&mut self, bytes: &[u8]) {
|
||||
self.buf.extend_from_slice(bytes);
|
||||
}
|
||||
|
||||
/// Extract the next complete `EventEnvelope` frame, if a full
|
||||
/// length-prefixed frame is buffered and parses. Unparseable
|
||||
/// frames are dropped (test-only surface).
|
||||
pub fn next_frame(&mut self) -> Option<EventEnvelope> {
|
||||
if self.buf.len() < 4 {
|
||||
return None;
|
||||
@@ -493,6 +516,8 @@ pub mod test_support {
|
||||
}
|
||||
|
||||
impl WsClient {
|
||||
/// Connect with a `Bearer` token header; the full WS stream is
|
||||
/// returned (upgrade succeeded).
|
||||
pub async fn connect_authorized(url: &str, token: &str) -> Result<Self, String> {
|
||||
let mut request = url
|
||||
.into_client_request()
|
||||
@@ -554,10 +579,18 @@ pub mod test_support {
|
||||
Self { sink, stream }
|
||||
}
|
||||
|
||||
/// Send one binary WS message.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics on a socket write failure — a test client that cannot
|
||||
/// send has a broken test, not a recoverable runtime state.
|
||||
pub async fn send_binary(&mut self, bytes: Vec<u8>) {
|
||||
self.send_binary_piece(&bytes).await;
|
||||
}
|
||||
|
||||
/// Send one binary WS message, in pieces (for split-frame
|
||||
/// tests). Same panic contract as [`Self::send_binary`].
|
||||
pub async fn send_binary_piece(&mut self, bytes: &[u8]) {
|
||||
use futures::SinkExt;
|
||||
self.sink
|
||||
@@ -568,6 +601,8 @@ pub mod test_support {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// Send one text WS message. Same panic contract as
|
||||
/// [`Self::send_binary`].
|
||||
pub async fn send_text(&mut self, text: &str) {
|
||||
use futures::SinkExt;
|
||||
self.sink
|
||||
@@ -616,6 +651,7 @@ pub mod test_support {
|
||||
}
|
||||
}
|
||||
|
||||
/// Close the WS with a normal-close frame.
|
||||
pub async fn close(&mut self) {
|
||||
use futures::SinkExt;
|
||||
let _ = self.sink.close().await;
|
||||
|
||||
Reference in New Issue
Block a user