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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//! The datagram substrate seam — `SPEC.md` §16.3.
use SocketAddr;
/// The datagram substrate an endpoint runs over. §16.3, ratified
/// 2026/08/14 (ruling 49).
///
/// # Normative properties
///
/// 1. **The application supplies it**, through `Endpoint::builder()`
/// (§16.2) — so an application needing its own socket options, a
/// dual-stack or per-interface arrangement, a tunnel, or a simulator
/// installs one without forking the crate.
/// 2. **It is not required to be `Send`**, and no `Send` bound may be
/// added to it or to the futures its methods return. The driver is a
/// single `!Send` actor, and the reasoning that keeps a DH provider
/// free of `Send` (a hardware static) keeps a `Wire` free of it.
/// 3. **Both methods take `&self`**, because the one driver task owns
/// the seam and drives both directions from it. A `Wire` needs no
/// interior handle duplication, and connections never send on socket
/// clones.
/// 4. **`testutil::FlakyWire` is a `Wire`** — the in-memory
/// implementation the paused-clock flow tests ride (§16.10), which is
/// why every timer in the spec is testable without a kernel, a port,
/// or a sleep.
///
/// # A failing `send_to` is traced, not acted on
///
/// When [`send_to`](Wire::send_to) returns `Err`, the driver **must**
/// trace it under `slither::io` (§18.2) against the connection whose
/// datagram it was, carrying the destination address and the underlying
/// error. It does **not** kill the connection, resolve any verb with an
/// error, or produce a `Notification`: liveness is receive-driven (§7.4),
/// and `ENETUNREACH` is the signal that *precedes* a successful roam
/// (§7.3), not one that follows a dead connection.
///
/// The obligation is the **driver's**, not the implementation's: a `Wire`
/// that traced its own failures would double-count, and would move a
/// protocol obligation onto application code.
///
/// # This trait is deliberately not dyn-compatible
///
/// The methods are `async fn` in trait, which desugars to a return-position
/// `impl Future`. That is what makes the returned future `Send` *iff* the
/// implementation's future is — `!Send` is admitted by construction rather
/// than required — and it is what §16.3's normative code block writes. The
/// price is that there is no `Box<dyn Wire>`: **the wire is a type
/// parameter, not an erased object.**
///
/// It is [`EndpointBuilder<I, W>`](super::EndpointBuilder) that carries the
/// `W`, and [`build`](super::EndpointBuilder::build) **erases it** — the
/// built [`Endpoint<I>`](super::Endpoint) names only its identity, because
/// the wire is moved into the spawned driver and never surfaces on a handle
/// again. This paragraph said `Endpoint<W: Wire>`, a type that has never
/// existed; the constraint it describes is real and lands one type earlier
/// than it claimed. This is recorded here
/// because there is no way to assert dyn-incompatibility in a test, and a
/// later slice should meet the constraint as documentation rather than as a
/// compiler error.
///
/// If type erasure is ever needed, the way in is a *private* `DynWire`
/// shim inside the shell that boxes the futures **without** a `Send`
/// bound. That keeps the allocation off the hot path for everyone who does
/// not need erasure, and keeps this trait as the spec writes it.
// The `async_fn_in_trait` lint warns that callers cannot add a `+ Send`
// bound to the returned futures. That is precisely what normative property
// 2 above requires, so the warning is the design working, not a defect.
// Ruling 277: target-gated, not feature-gated — on wasm there is no UDP
// socket to wrap and tokio's `net` feature does not compile at all, so the
// impl (and the `net` dependency, see Cargo.toml) exists everywhere except
// wasm. The native surface is byte-identical.