moqtap_client/draft17/event.rs
1//! Client event types emitted by a MoQT connection.
2
3use moqtap_codec::dispatch::{
4 AnyControlMessage, AnyDatagramHeader, AnyFetchHeader, AnySubgroupHeader,
5};
6use moqtap_codec::draft17::data_stream::{FetchHeader, SubgroupHeader, SubgroupObject};
7
8/// Direction of a message or stream relative to this endpoint.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum Direction {
11 /// Sent (outgoing).
12 Send,
13 /// Received (incoming).
14 Receive,
15}
16
17/// The kind of stream an event refers to.
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub enum StreamKind {
20 /// Subgroup data stream.
21 Subgroup,
22 /// Fetch data stream.
23 Fetch,
24 /// Datagram.
25 Datagram,
26 /// Request stream: the bidirectional stream one request and its response
27 /// travel on.
28 ///
29 /// Draft-17 Section 3.3 moved requests off the control plane and gave each
30 /// one a bidirectional stream that begins with the request message. This
31 /// is the only kind here that is not a data stream, and it is named
32 /// because an observer that could not name it would see a request message
33 /// with no stream to attach it to.
34 Request,
35}
36
37/// Events emitted by a MoQT connection.
38///
39/// This enum is `#[non_exhaustive]` -- new variants may be added in minor
40/// releases. Downstream `match` arms should include a wildcard `_ =>` branch.
41#[non_exhaustive]
42#[derive(Debug, Clone)]
43pub enum ClientEvent {
44 /// MoQT setup handshake completed.
45 SetupComplete {
46 /// The negotiated MoQT version (from ALPN in draft-17).
47 negotiated_version: u64,
48 },
49
50 /// A control message was sent or received.
51 ControlMessage {
52 /// Whether the message was sent or received.
53 direction: Direction,
54 /// The decoded control message.
55 message: AnyControlMessage,
56 /// The transport-level identifier of the stream the message travelled
57 /// on when that stream is a request stream, and `None` when it is the
58 /// control stream.
59 ///
60 /// Draft-17 responses carry no request id: the stream is the
61 /// correlation. Without this an observer sees a SUBSCRIBE_OK with
62 /// nothing to say which SUBSCRIBE it answers, and cannot tell a
63 /// message on the control stream from one on a request stream.
64 stream_id: Option<u64>,
65 /// The raw wire bytes of the framed message (type + length + payload).
66 /// `None` if raw capture is not available.
67 raw: Option<Vec<u8>>,
68 },
69
70 /// A data stream was opened.
71 StreamOpened {
72 /// Whether we opened (Send) or accepted (Receive) the stream.
73 direction: Direction,
74 /// The type of data stream.
75 stream_kind: StreamKind,
76 /// Transport-level stream identifier.
77 stream_id: u64,
78 },
79
80 /// A data stream header was decoded after the stream opened.
81 DataStreamHeader {
82 /// Transport-level stream identifier.
83 stream_id: u64,
84 /// Whether we opened (Send) or accepted (Receive) the stream.
85 direction: Direction,
86 /// The parsed subgroup header.
87 header: AnySubgroupHeader,
88 },
89
90 /// A fetch response stream header was decoded.
91 FetchStreamHeader {
92 /// Transport-level stream identifier.
93 stream_id: u64,
94 /// Whether we opened (Send) or accepted (Receive) the stream.
95 direction: Direction,
96 /// The parsed fetch header.
97 header: AnyFetchHeader,
98 },
99
100 /// A subgroup object header was decoded on a subgroup stream.
101 SubgroupObjectReceived {
102 /// Transport-level stream identifier.
103 stream_id: u64,
104 /// Direction (Send when emitted from a writer, Receive from a reader).
105 direction: Direction,
106 /// The decoded subgroup header (for context).
107 subgroup_header: SubgroupHeader,
108 /// The decoded subgroup object.
109 object: SubgroupObject,
110 },
111
112 /// A fetch header was decoded on a fetch stream.
113 FetchHeaderReceived {
114 /// Transport-level stream identifier.
115 stream_id: u64,
116 /// Direction (Send when emitted from a writer, Receive from a reader).
117 direction: Direction,
118 /// The decoded fetch header.
119 header: FetchHeader,
120 },
121
122 /// A datagram was sent or received.
123 DatagramReceived {
124 /// Whether sent or received.
125 direction: Direction,
126 /// The parsed datagram header.
127 header: AnyDatagramHeader,
128 /// Size of the payload in bytes.
129 payload_len: usize,
130 },
131
132 /// A data stream was closed.
133 StreamClosed {
134 /// Transport-level stream identifier.
135 stream_id: u64,
136 /// Error code (0 = clean close).
137 error_code: u64,
138 },
139
140 /// Session entered draining state (GOAWAY received).
141 Draining {
142 /// The new session URI from the GOAWAY message.
143 new_session_uri: Vec<u8>,
144 },
145
146 /// Connection was closed.
147 Closed {
148 /// Application error code.
149 code: u32,
150 /// Human-readable reason.
151 reason: Vec<u8>,
152 },
153
154 /// A transport or protocol error occurred.
155 Error {
156 /// Error description.
157 error: String,
158 },
159}