1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! **The wire's framing** — yog's `docs/REMOTE.md` §3 is the authority and
//! this is the seat's end of it: *"a big-endian `u32` byte length, then that many
//! bytes of JSON. A request is one frame; an answer is N ≥ 1 reply frames
//! followed by a zero-length frame, which is the terminator."*
//!
//! The protocol document states why it is length-delimited rather than
//! newline-delimited and this file does not restate it. What matters on this
//! side is the consequence: a reader never scans, the allocation is bounded
//! before it is made, and a zero-length frame is not a JSON value, so nothing a
//! payload can say collides with the terminator.
//!
//! **The streaming form is not a second form.** Every answer is a stream, so a
//! follow-class read — the live tail the window's follow lane will hold open —
//! is the general path with more than one frame in it. There is no flag, no
//! version and no second reader here, and there is nothing to add when that
//! lane lands.
use ;
use Value;
/// The largest frame either end will write or read: 16 MiB. It is a fact about
/// the wire and not about this end, so it is the number REMOTE §3's
/// implementation fixed rather than one a seat chooses — a reader that accepted
/// more would accept a frame the peer will never send, and one that accepted
/// less would refuse a frame the peer may.
pub const MAX_FRAME: usize = 16 * 1024 * 1024;
/// The frame header's width — a big-endian `u32`.
const HEADER: usize = 4;
/// Write one JSON frame.
///
/// The body is [`Value::to_string`] rather than a fallible serialization: a
/// `Value` is JSON already, so the error arm of `to_string(v)?` cannot be
/// reached from any input, and an unreachable branch is an untested one.
/// Write the end-of-stream terminator: a zero-length frame.
/// Read one JSON frame: `Some(value)` a frame, `None` the terminator. An
/// oversized length, a short stream and a body that is not JSON are all errors
/// — the strict-decode discipline the boundary keeps, held at the framing so
/// nothing above it has to.
/// The length-prefixed write both spellings above share.
///
/// The bound and the header's own width are **one decision**, so they are one
/// match: a body larger than a `u32` can count and a body larger than the wire
/// permits are the same refusal, and splitting them would leave a conversion
/// arm no input on a 64-bit machine can reach.
pub
/// The length-prefixed read: `None` for the zero-length terminator.
/// The one refusal a length can earn, said the same way in both directions.