rsrs_core/frame/
payload.rs

1use recode::bytes::BytesMut;
2use recode::codec::*;
3
4use crate::{frame, FrameFlags};
5
6frame! {
7    /// PAYLOAD Frame (0x0A)
8    ///
9    /// # Frame Contents
10    ///
11    /// ```text
12    ///  0                   1                   2                   3
13    ///  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
14    /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
15    /// |                           Stream ID                           |
16    /// +-----------+-+-+-+-+-+---------+-------------------------------+
17    /// |Frame Type |0|M|F|C|N|  Flags  |
18    /// +-------------------------------+-------------------------------+
19    ///                      Metadata & Data
20    /// ```
21    ///
22    /// ### Valid combinations of (C)omplete and (N)ext flags are:
23    ///
24    /// * Both (C)omplete and (N)ext set meaning PAYLOAD contains data and signals stream completion.
25    ///   *For example: An Observable stream receiving onNext(payload) followed by onComplete().*
26    ///
27    /// * Just (C)omplete set meaning PAYLOAD contains no data and only signals stream completion.
28    ///   *For example: An Observable stream receiving onComplete().*
29    /// * Just (N)ext set meaning PAYLOAD contains data stream is NOT completed.
30    ///   *For example: An Observable stream receiving onNext(payload).*
31    ///
32    /// **A PAYLOAD MUST NOT have both (C)complete and (N)ext empty (false).**
33    ///
34    /// The reason for the (N)ext flag instead of just deriving from Data
35    /// length being > 0 is that 0 length data can be considered a valid
36    /// PAYLOAD resulting in a delivery to the application layer with a PAYLOAD
37    /// containing 0 bytes of data.
38    ///
39    /// For example: An Observable stream receiving data via onNext(payload)
40    /// where payload contains 0 bytes of data.
41    Payload [header] {
42        #mask = [METADATA | FOLLOW | COMPLETE | NEXT];
43
44        /// Payload Metadata
45        @skip_if("!header.has(FrameFlags::METADATA)");
46        @with("LengthPrefixed::<u24>");
47        pub metadata: BytesMut => [ set (METADATA if !metadata.is_empty()) ];
48
49        /// Payload Data
50        @with("Unprefixed");
51        pub data: BytesMut => [ set (NEXT if !data.is_empty()) ];
52    }
53}