Skip to main content

rig_core/wire/
document.rs

1//! The reply document a reply's frames rebuild. Every [`Wire`](super::Wire)
2//! names one [`Reassemble`] type. The driver hands it each frame of a reply
3//! whose transport reported no whole document, before the decoder reads the
4//! frame, and records what it finishes with as the reply's `raw`. A
5//! completion decoder cannot write `raw` itself, so a streamed reply's
6//! `raw` has one owner per wire. A wire names a reassembler only for an
7//! operation it [`Serves`], and [`Unreassembled`], which records nothing,
8//! serves no completion.
9//!
10//! ```
11//! use rig_core::wire::document::{Reassemble, Unreassembled};
12//!
13//! let mut document = Unreassembled;
14//! Reassemble::<String>::absorb(&mut document, &"frame".to_owned());
15//! assert!(Reassemble::<String>::finish(document).is_null());
16//! ```
17
18use crate::wasm_compat::WasmCompatSend;
19use crate::wire::{Free, Operation};
20
21/// Rebuilds one reply's provider document from the frames it arrived in.
22///
23/// A fresh value per reply. `absorb` sees every frame the driver reads, in
24/// arrival order, including frames the decoder classifies as unknown or
25/// corrupt. `finish` runs once, when the reply ends, fails or is cut
26/// short; a reply that did not end yields the document so far.
27pub trait Reassemble<Frame>: Default + WasmCompatSend + 'static {
28    /// Absorb one frame of the reply.
29    fn absorb(&mut self, frame: &Frame);
30
31    /// The document the absorbed frames add up to. `Null` records none.
32    fn finish(self) -> serde_json::Value;
33}
34
35/// The reassembler of a wire whose decoders record `raw` themselves, which
36/// only an operation with [`Free`] events can: it records
37/// nothing.
38#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
39pub struct Unreassembled;
40
41impl<Frame> Reassemble<Frame> for Unreassembled {
42    fn absorb(&mut self, _frame: &Frame) {}
43
44    fn finish(self) -> serde_json::Value {
45        serde_json::Value::Null
46    }
47}
48
49/// The operations whose wires may name a reassembler: a wire's
50/// [`Reassembler`](super::Wire::Reassembler) must serve its operation.
51///
52/// [`Unreassembled`] serves only an operation whose decoders record `raw`
53/// themselves ([`Free`] events), so a completion wire cannot name it and
54/// must name a reassembler that rebuilds its document:
55///
56/// ```compile_fail,E0271
57/// use rig_core::operation::Completion;
58/// use rig_core::wire::document::{Serves, Unreassembled};
59///
60/// fn completion_reassembler<R: Serves<Completion>>() {}
61/// completion_reassembler::<Unreassembled>();
62/// ```
63pub trait Serves<Op: Operation> {}
64
65impl<Op: Operation<Emit = Free>> Serves<Op> for Unreassembled {}