iscsi_client_rs/models/data/
common.rs1use core::fmt;
9
10use anyhow::{Result, bail};
11use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
12
13bitflags::bitflags! {
14 #[derive(Default, Debug, PartialEq)]
15 pub struct DataOutFlags: u8 {
20 const FINAL = 0b1000_0000;
22 }
23}
24
25impl TryFrom<u8> for DataOutFlags {
26 type Error = anyhow::Error;
27
28 fn try_from(value: u8) -> Result<Self, Self::Error> {
29 DataOutFlags::from_bits(value)
30 .ok_or_else(|| anyhow::anyhow!("invalid DataOutFlags: {:#08b}", value))
31 }
32}
33
34#[repr(transparent)]
38#[derive(Default, Clone, PartialEq, Eq, FromBytes, IntoBytes, KnownLayout, Immutable)]
39pub struct RawDataOutFlags(u8);
40
41impl RawDataOutFlags {
42 pub const FINAL: u8 = 0b1000_0000;
44
45 #[inline]
47 pub const fn raw(&self) -> u8 {
48 self.0
49 }
50
51 #[inline]
53 pub const fn new_raw(v: u8) -> Self {
54 Self(v)
55 }
56
57 #[inline]
59 pub fn fin(&self) -> bool {
60 self.0 & Self::FINAL != 0
61 }
62
63 #[inline]
65 pub fn set_fin(&mut self, on: bool) {
66 if on {
67 self.0 |= Self::FINAL;
68 } else {
69 self.0 &= !Self::FINAL;
70 }
71 }
72}
73
74impl From<DataOutFlags> for RawDataOutFlags {
77 #[inline]
78 fn from(f: DataOutFlags) -> Self {
79 Self(f.bits())
80 }
81}
82
83impl TryFrom<RawDataOutFlags> for DataOutFlags {
84 type Error = anyhow::Error;
85
86 #[inline]
87 fn try_from(r: RawDataOutFlags) -> Result<Self> {
88 DataOutFlags::from_bits(r.raw())
89 .ok_or_else(|| anyhow::anyhow!("invalid DataOutFlags: {:#010b}", r.raw()))
90 }
91}
92
93bitflags::bitflags! {
94 #[derive(Default, Debug, PartialEq)]
95 pub struct DataInFlags: u8 {
100 const FINAL = 1 << 7;
102 const A = 1 << 6;
104 const O = 1 << 2;
107 const U = 1 << 1;
109 const S = 1 << 0;
111 }
112}
113
114impl TryFrom<u8> for DataInFlags {
115 type Error = anyhow::Error;
116
117 fn try_from(value: u8) -> Result<Self, Self::Error> {
118 let tmp = DataInFlags::from_bits(value)
119 .ok_or_else(|| anyhow::anyhow!("invalid DataOutFlags: {:#08b}", value))?;
120
121 if tmp.contains(DataInFlags::U) && tmp.contains(DataInFlags::O) {
122 bail!("Protocol error cause U && O both presented")
123 }
124
125 Ok(tmp)
126 }
127}
128
129#[repr(transparent)]
134#[derive(Default, PartialEq, Eq, FromBytes, IntoBytes, KnownLayout, Immutable)]
135pub struct RawDataInFlags(u8);
136
137impl RawDataInFlags {
138 pub const A: u8 = 1 << 6;
140 pub const FINAL: u8 = 1 << 7;
142 pub const O: u8 = 1 << 2;
144 const RESERVED_MASK: u8 = 0b0011_1000;
145 pub const S: u8 = 1 << 0;
147 pub const U: u8 = 1 << 1;
149
150 #[inline]
152 pub const fn raw(&self) -> u8 {
153 self.0
154 }
155
156 #[inline]
158 pub const fn new_raw(v: u8) -> Self {
159 Self(v)
160 }
161
162 #[inline]
164 pub fn fin(&self) -> bool {
165 self.0 & Self::FINAL != 0
166 }
167
168 #[inline]
170 pub fn ack(&self) -> bool {
171 self.0 & Self::A != 0
172 }
173
174 #[inline]
176 pub fn o(&self) -> bool {
177 self.0 & Self::O != 0
178 }
179
180 #[inline]
182 pub fn u(&self) -> bool {
183 self.0 & Self::U != 0
184 }
185
186 #[inline]
188 pub fn s(&self) -> bool {
189 self.0 & Self::S != 0
190 }
191
192 #[inline]
194 pub fn set_fin(&mut self, on: bool) {
195 Self::set_bit(&mut self.0, Self::FINAL, on)
196 }
197
198 #[inline]
200 pub fn set_ack(&mut self, on: bool) {
201 Self::set_bit(&mut self.0, Self::A, on)
202 }
203
204 #[inline]
206 pub fn set_o(&mut self, on: bool) {
207 Self::set_pair(&mut self.0, Self::O, Self::U, on)
208 }
209
210 #[inline]
212 pub fn set_u(&mut self, on: bool) {
213 Self::set_pair(&mut self.0, Self::U, Self::O, on)
214 }
215
216 #[inline]
218 pub fn set_s(&mut self, on: bool) {
219 Self::set_bit(&mut self.0, Self::S, on);
220 if on {
221 self.set_fin(true);
222 } }
224
225 #[inline]
226 fn set_bit(v: &mut u8, bit: u8, on: bool) {
227 if on {
228 *v |= bit;
229 } else {
230 *v &= !bit;
231 }
232 }
233
234 #[inline]
236 fn set_pair(v: &mut u8, set_bit: u8, clear_bit: u8, on: bool) {
237 if on {
238 *v |= set_bit;
239 *v &= !clear_bit;
240 } else {
241 *v &= !set_bit;
242 }
243 }
244
245 #[inline]
247 pub fn validate(&self) -> Result<()> {
248 if self.0 & Self::RESERVED_MASK != 0 {
249 bail!(
250 "protocol error: reserved bits set in DataInFlags: {:#010b}",
251 self.0
252 );
253 }
254 if self.u() && self.o() {
255 bail!("protocol error: both U and O set");
256 }
257 if self.s() && !self.fin() {
258 bail!("protocol error: S=1 requires F=1");
259 }
260 Ok(())
261 }
262}
263
264impl From<DataInFlags> for RawDataInFlags {
267 #[inline]
268 fn from(f: DataInFlags) -> Self {
269 Self(f.bits())
270 }
271}
272
273impl TryFrom<RawDataInFlags> for DataInFlags {
274 type Error = anyhow::Error;
275
276 #[inline]
277 fn try_from(r: RawDataInFlags) -> Result<Self> {
278 r.validate()?;
279 DataInFlags::from_bits(r.raw())
280 .ok_or_else(|| anyhow::anyhow!("invalid DataInFlags: {:#010b}", r.raw()))
281 }
282}
283
284impl fmt::Debug for RawDataOutFlags {
286 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287 write!(f, "RawDataOutFlags {{ ")?;
288 if self.fin() {
289 write!(f, "FIN")?;
290 }
291 write!(f, " }}")
292 }
293}
294
295impl fmt::Debug for RawDataInFlags {
296 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
297 let raw = self.raw();
298 let reserved_bits = (raw & Self::RESERVED_MASK) >> 3;
299
300 write!(f, "RawDataInFlags {{ ")?;
301
302 if self.fin() {
303 write!(f, "FIN|")?;
304 }
305 if self.ack() {
306 write!(f, "A|")?;
307 }
308 if self.o() {
309 write!(f, "O|")?;
310 }
311 if self.u() {
312 write!(f, "U|")?;
313 }
314 if self.s() {
315 write!(f, "S|")?;
316 }
317
318 if reserved_bits != 0 {
319 write!(f, "reserved_bits=0b{:03b}|", reserved_bits)?;
320 }
321 if self.u() && self.o() {
322 write!(f, "INVALID:U&O|")?;
323 }
324 if self.s() && !self.fin() {
325 write!(f, "INVALID:S_without_F|")?;
326 }
327
328 write!(f, " }}")
329 }
330}