binate/frame/
flags.rs

1/// Type of frame.
2#[non_exhaustive]
3#[allow(non_camel_case_types)]
4#[allow(clippy::upper_case_acronyms)]
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum FrameType {
7    /// Sent by client to initiate protocol processing.
8    SETUP,
9    /// Sent by Responder to grant the ability to send requests.
10    LEASE,
11    /// Connection keepalive.
12    KEEPALIVE,
13    /// Request single response.
14    REQUEST_RESPONSE,
15    /// A single one-way message.
16    REQUEST_FNF,
17    /// Request a completable stream.
18    REQUEST_STREAM,
19    /// Request a completable stream in both directions.
20    REQUEST_CHANNEL,
21    /// Request N more items with Reactive Streams semantics.
22    REQUEST_N,
23    /// Cancel outstanding request.
24    CANCEL,
25    /// Payload on a stream. For example, response to a request, or message on a channel.
26    PAYLOAD,
27    /// Error at connection or application level.
28    ERROR,
29    /// Asynchronous Metadata frame
30    METADATA_PUSH,
31    /// Replaces SETUP for Resuming Operation (optional)
32    RESUME,
33    /// Sent in response to a RESUME if resuming operation possible (optional)
34    RESUME_OK,
35    /// Used To Extend more frame types as well as extensions.
36    EXT,
37}
38
39impl FrameType {
40    /// Specify the frame type with the raw value described in the [`Frame Types`] section of the
41    /// RSocket protocol spec. This will return `None` if the given raw value is unrecognized.
42    ///
43    /// [`Frame Types`]: https://rsocket.io/about/protocol/#frame-types
44    pub fn from_value(val: u16) -> Option<FrameType> {
45        match val {
46            0x01 => Some(FrameType::SETUP),
47            0x02 => Some(FrameType::LEASE),
48            0x03 => Some(FrameType::KEEPALIVE),
49            0x04 => Some(FrameType::REQUEST_RESPONSE),
50            0x05 => Some(FrameType::REQUEST_FNF),
51            0x06 => Some(FrameType::REQUEST_STREAM),
52            0x07 => Some(FrameType::REQUEST_CHANNEL),
53            0x08 => Some(FrameType::REQUEST_N),
54            0x09 => Some(FrameType::CANCEL),
55            0x0A => Some(FrameType::PAYLOAD),
56            0x0B => Some(FrameType::ERROR),
57            0x0C => Some(FrameType::METADATA_PUSH),
58            0x0D => Some(FrameType::RESUME),
59            0x0E => Some(FrameType::RESUME_OK),
60            0x3F => Some(FrameType::EXT),
61            _ => None,
62        }
63    }
64
65    /// Convert from underlying bit representation, if the bit representation contains a valid
66    /// frame type.
67    ///
68    /// In other words, the higher 6-bit of the given bit pattern will convert to a [`FrameType`].
69    ///
70    /// ```text
71    /// 0                   1                   2                   3
72    /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
73    /// +-----------+-+-+-+-+-----------+-------------------------------+
74    /// |Frame Type |I|M|     Flags     |
75    /// +-----------+-+-+-+-+-----------+-------------------------------+
76    /// ```
77    pub fn from_bits(bits: u16) -> Option<FrameType> {
78        match bits >> 10 {
79            0x01 => Some(FrameType::SETUP),
80            0x02 => Some(FrameType::LEASE),
81            0x03 => Some(FrameType::KEEPALIVE),
82            0x04 => Some(FrameType::REQUEST_RESPONSE),
83            0x05 => Some(FrameType::REQUEST_FNF),
84            0x06 => Some(FrameType::REQUEST_STREAM),
85            0x07 => Some(FrameType::REQUEST_CHANNEL),
86            0x08 => Some(FrameType::REQUEST_N),
87            0x09 => Some(FrameType::CANCEL),
88            0x0A => Some(FrameType::PAYLOAD),
89            0x0B => Some(FrameType::ERROR),
90            0x0C => Some(FrameType::METADATA_PUSH),
91            0x0D => Some(FrameType::RESUME),
92            0x0E => Some(FrameType::RESUME_OK),
93            0x3F => Some(FrameType::EXT),
94            _ => None,
95        }
96    }
97
98    /// Returns the corresponding raw value of this frame type. The raw value is described in the
99    /// [`Frame Types`] section of the RSocket protocol spec.
100    ///
101    /// [`Frame Types`]: https://rsocket.io/about/protocol/#frame-types
102    pub fn value(self) -> u16 {
103        match self {
104            FrameType::SETUP => 0x01,
105            FrameType::LEASE => 0x02,
106            FrameType::KEEPALIVE => 0x03,
107            FrameType::REQUEST_RESPONSE => 0x04,
108            FrameType::REQUEST_FNF => 0x05,
109            FrameType::REQUEST_STREAM => 0x06,
110            FrameType::REQUEST_CHANNEL => 0x07,
111            FrameType::REQUEST_N => 0x08,
112            FrameType::CANCEL => 0x09,
113            FrameType::PAYLOAD => 0x0A,
114            FrameType::ERROR => 0x0B,
115            FrameType::METADATA_PUSH => 0x0C,
116            FrameType::RESUME => 0x0D,
117            FrameType::RESUME_OK => 0x0E,
118            FrameType::EXT => 0x3F,
119        }
120    }
121
122    /// Convert this frame type to a bit representation, with the higher 6-bit of the return value
123    /// setting to the raw value of the frame type.
124    ///
125    /// ```text
126    /// 0                   1                   2                   3
127    /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
128    /// +-----------+-+-+-+-+-----------+-------------------------------+
129    /// |Frame Type |I|M|     Flags     |
130    /// +-----------+-+-+-+-+-----------+-------------------------------+
131    /// ```
132    pub fn bits(self) -> u16 {
133        let val = match self {
134            FrameType::SETUP => 0x01,
135            FrameType::LEASE => 0x02,
136            FrameType::KEEPALIVE => 0x03,
137            FrameType::REQUEST_RESPONSE => 0x04,
138            FrameType::REQUEST_FNF => 0x05,
139            FrameType::REQUEST_STREAM => 0x06,
140            FrameType::REQUEST_CHANNEL => 0x07,
141            FrameType::REQUEST_N => 0x08,
142            FrameType::CANCEL => 0x09,
143            FrameType::PAYLOAD => 0x0A,
144            FrameType::ERROR => 0x0B,
145            FrameType::METADATA_PUSH => 0x0C,
146            FrameType::RESUME => 0x0D,
147            FrameType::RESUME_OK => 0x0E,
148            FrameType::EXT => 0x3F,
149        };
150        val << 10
151    }
152}
153
154bitflags! {
155    /// Frame header flags.
156    pub struct Flags: u16 {
157        /// The frame can be ignored.
158        const IGNORE           = 0b01_0000_0000;
159        /// Metadata present.
160        const METADATA         = 0b00_1000_0000;
161        /// More fragments follow this fragment.
162        const FOLLOWS           = 0b00_0100_0000;
163        /// Client requests resume capability if possible.
164        const RESUME           = 0b00_0100_0000;
165        /// Respond with KEEPALIVE.
166        const RESPOND          = 0b00_0100_0000;
167        /// Bit to indicate stream completion.
168        const COMPLETE         = 0b00_0010_0000;
169        /// Will honor LEASE.
170        const LEASE            = 0b00_0010_0000;
171        /// Bit to indicate Next (Payload Data and/or Metadata present).
172        const NEXT             = 0b00_0001_0000;
173    }
174}
175
176impl Flags {
177    /// Returns true if the Flags have the IGNORE bit set.
178    pub fn is_ignore(&self) -> bool {
179        self.contains(Flags::IGNORE)
180    }
181
182    /// Returns true if the Flags have the METADATA bit set.
183    pub fn is_metadata(&self) -> bool {
184        self.contains(Flags::METADATA)
185    }
186
187    /// Returns true if the Flags have the FOLLOWS bit set.
188    pub fn is_follows(&self) -> bool {
189        self.contains(Flags::FOLLOWS)
190    }
191
192    /// Returns true if the Flags have the RESUME bit set.
193    pub fn is_resume(&self) -> bool {
194        self.contains(Flags::RESUME)
195    }
196
197    /// Returns true if the Flags have the RESPOND bit set.
198    pub fn is_respond(&self) -> bool {
199        self.contains(Flags::RESPOND)
200    }
201
202    /// Returns true if the Flags have the COMPLETE bit set.
203    pub fn is_complete(&self) -> bool {
204        self.contains(Flags::COMPLETE)
205    }
206
207    /// Returns true if the Flags have the LEASE bit set.
208    pub fn is_lease(&self) -> bool {
209        self.contains(Flags::LEASE)
210    }
211
212    /// Returns true if the Flags have the NEXT bit set.
213    pub fn is_next(&self) -> bool {
214        self.contains(Flags::NEXT)
215    }
216}
217
218#[cfg(test)]
219mod tests {
220    use super::*;
221
222    #[test]
223    fn from_value() {
224        assert_eq!(FrameType::from_value(0x01).unwrap(), FrameType::SETUP);
225        assert_eq!(FrameType::from_value(0x02).unwrap(), FrameType::LEASE);
226        assert_eq!(FrameType::from_value(0x03).unwrap(), FrameType::KEEPALIVE);
227        assert_eq!(
228            FrameType::from_value(0x04).unwrap(),
229            FrameType::REQUEST_RESPONSE
230        );
231        assert_eq!(
232            FrameType::from_value(0x05).unwrap(),
233            FrameType::REQUEST_FNF
234        );
235        assert_eq!(
236            FrameType::from_value(0x06).unwrap(),
237            FrameType::REQUEST_STREAM
238        );
239        assert_eq!(
240            FrameType::from_value(0x07).unwrap(),
241            FrameType::REQUEST_CHANNEL
242        );
243        assert_eq!(FrameType::from_value(0x08).unwrap(), FrameType::REQUEST_N);
244        assert_eq!(FrameType::from_value(0x09).unwrap(), FrameType::CANCEL);
245        assert_eq!(FrameType::from_value(0x0A).unwrap(), FrameType::PAYLOAD);
246        assert_eq!(FrameType::from_value(0x0B).unwrap(), FrameType::ERROR);
247        assert_eq!(
248            FrameType::from_value(0x0C).unwrap(),
249            FrameType::METADATA_PUSH
250        );
251        assert_eq!(FrameType::from_value(0x0D).unwrap(), FrameType::RESUME);
252        assert_eq!(FrameType::from_value(0x0E).unwrap(), FrameType::RESUME_OK);
253        assert_eq!(FrameType::from_value(0x3F).unwrap(), FrameType::EXT);
254        assert!(FrameType::from_value(0x00).is_none());
255    }
256
257    #[test]
258    fn from_bits() {
259        assert_eq!(
260            FrameType::from_bits(0x01 << 10).unwrap(),
261            FrameType::SETUP
262        );
263        assert_eq!(
264            FrameType::from_bits(0x02 << 10).unwrap(),
265            FrameType::LEASE
266        );
267        assert_eq!(
268            FrameType::from_bits(0x03 << 10).unwrap(),
269            FrameType::KEEPALIVE
270        );
271        assert_eq!(
272            FrameType::from_bits(0x04 << 10).unwrap(),
273            FrameType::REQUEST_RESPONSE
274        );
275        assert_eq!(
276            FrameType::from_bits(0x05 << 10).unwrap(),
277            FrameType::REQUEST_FNF
278        );
279        assert_eq!(
280            FrameType::from_bits(0x06 << 10).unwrap(),
281            FrameType::REQUEST_STREAM
282        );
283        assert_eq!(
284            FrameType::from_bits(0x07 << 10).unwrap(),
285            FrameType::REQUEST_CHANNEL
286        );
287        assert_eq!(
288            FrameType::from_bits(0x08 << 10).unwrap(),
289            FrameType::REQUEST_N
290        );
291        assert_eq!(
292            FrameType::from_bits(0x09 << 10).unwrap(),
293            FrameType::CANCEL
294        );
295        assert_eq!(
296            FrameType::from_bits(0x0A << 10).unwrap(),
297            FrameType::PAYLOAD
298        );
299        assert_eq!(
300            FrameType::from_bits(0x0B << 10).unwrap(),
301            FrameType::ERROR
302        );
303        assert_eq!(
304            FrameType::from_bits(0x0C << 10).unwrap(),
305            FrameType::METADATA_PUSH
306        );
307        assert_eq!(
308            FrameType::from_bits(0x0D << 10).unwrap(),
309            FrameType::RESUME
310        );
311        assert_eq!(
312            FrameType::from_bits(0x0E << 10).unwrap(),
313            FrameType::RESUME_OK
314        );
315        assert_eq!(FrameType::from_bits(0x3F << 10).unwrap(), FrameType::EXT);
316        assert!(FrameType::from_bits(0x00).is_none());
317    }
318
319    #[test]
320    fn value() {
321        assert_eq!(FrameType::SETUP.value(), 0x01);
322    }
323
324    #[test]
325    fn bits() {
326        assert_eq!(FrameType::SETUP.bits(), 0b0000_0100_0000_0000);
327    }
328}