1use crate::MsgDescHot;
4use bytes::Bytes;
5
6#[derive(Debug)]
8pub enum Payload {
9 Inline,
11 Owned(Vec<u8>),
13 Bytes(Bytes),
15 Pooled(PooledBuf),
19 #[cfg(feature = "shm")]
21 Shm(crate::transport::shm::SlotGuard),
22}
23
24impl Payload {
25 pub fn as_slice<'a>(&'a self, desc: &'a MsgDescHot) -> &'a [u8] {
27 match self {
28 Payload::Inline => desc.inline_payload(),
29 Payload::Owned(buf) => buf.as_slice(),
30 Payload::Bytes(buf) => buf.as_ref(),
31 Payload::Pooled(buf) => buf.as_ref(),
32 #[cfg(feature = "shm")]
33 Payload::Shm(guard) => guard.as_ref(),
34 }
35 }
36
37 pub fn external_slice(&self) -> Option<&[u8]> {
42 match self {
43 Payload::Inline => None,
44 Payload::Owned(buf) => Some(buf.as_slice()),
45 Payload::Bytes(buf) => Some(buf.as_ref()),
46 Payload::Pooled(buf) => Some(buf.as_ref()),
47 #[cfg(feature = "shm")]
48 Payload::Shm(guard) => Some(guard.as_ref()),
49 }
50 }
51
52 pub fn len(&self, desc: &MsgDescHot) -> usize {
54 if let Some(ext) = self.external_slice() {
55 ext.len()
56 } else {
57 desc.payload_len as usize
58 }
59 }
60
61 pub fn is_inline(&self) -> bool {
63 matches!(self, Payload::Inline)
64 }
65}
66
67#[derive(Debug)]
69pub struct PooledBuf(Bytes);
70
71impl AsRef<[u8]> for PooledBuf {
72 fn as_ref(&self) -> &[u8] {
73 self.0.as_ref()
74 }
75}
76
77#[derive(Debug)]
79pub struct Frame {
80 pub desc: MsgDescHot,
82 pub payload: Payload,
84}
85
86impl Frame {
87 pub fn new(desc: MsgDescHot) -> Self {
89 Self {
90 desc,
91 payload: Payload::Inline,
92 }
93 }
94
95 pub fn with_inline_payload(mut desc: MsgDescHot, payload: &[u8]) -> Option<Self> {
97 if payload.len() > crate::INLINE_PAYLOAD_SIZE {
98 return None;
99 }
100 desc.payload_slot = crate::INLINE_PAYLOAD_SLOT;
101 desc.payload_generation = 0;
102 desc.payload_offset = 0;
103 desc.payload_len = payload.len() as u32;
104 desc.inline_payload[..payload.len()].copy_from_slice(payload);
105 Some(Self {
106 desc,
107 payload: Payload::Inline,
108 })
109 }
110
111 pub fn with_payload(mut desc: MsgDescHot, payload: Vec<u8>) -> Self {
113 desc.payload_slot = 0;
114 desc.payload_generation = 0;
115 desc.payload_offset = 0;
116 desc.payload_len = payload.len() as u32;
117 Self {
118 desc,
119 payload: Payload::Owned(payload),
120 }
121 }
122
123 pub fn with_bytes(mut desc: MsgDescHot, payload: Bytes) -> Self {
125 desc.payload_slot = 0;
126 desc.payload_generation = 0;
127 desc.payload_offset = 0;
128 desc.payload_len = payload.len() as u32;
129 Self {
130 desc,
131 payload: Payload::Bytes(payload),
132 }
133 }
134
135 pub fn payload_bytes(&self) -> &[u8] {
137 self.payload.as_slice(&self.desc)
138 }
139}