smb_dtyp/binrw_util/
boolean.rs

1//! [`Boolean`][crate::Boolean] implementation for binrw.
2
3use binrw::{Endian, prelude::*};
4use std::io::{Read, Seek, Write};
5
6/// A simple Boolean type that reads and writes as a single byte.
7/// Any non-zero value is considered `true`, as defined by MS-FSCC 2.1.8.
8/// Similar to the WinAPI `BOOL` type.
9///
10/// This type supports `std::size_of::<Boolean>() == 1`, ensuring it is 1 byte in size.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct Boolean(bool);
13
14impl Boolean {
15    const _VALIDATE_SIZE_OF: [u8; 1] = [0; size_of::<Self>()];
16}
17
18impl BinRead for Boolean {
19    type Args<'a> = ();
20
21    fn read_options<R: Read + Seek>(
22        reader: &mut R,
23        _: Endian,
24        _: Self::Args<'_>,
25    ) -> binrw::BinResult<Self> {
26        let value: u8 = u8::read_options(reader, Endian::Little, ())?;
27        Ok(Boolean(value != 0))
28    }
29}
30
31impl BinWrite for Boolean {
32    type Args<'a> = ();
33
34    fn write_options<W: Write + Seek>(
35        &self,
36        writer: &mut W,
37        _: Endian,
38        _: Self::Args<'_>,
39    ) -> binrw::BinResult<()> {
40        let value: u8 = if self.0 { 1 } else { 0 };
41        value.write_options(writer, Endian::Little, ())
42    }
43}
44
45impl From<bool> for Boolean {
46    fn from(value: bool) -> Self {
47        Boolean(value)
48    }
49}
50
51impl From<Boolean> for bool {
52    fn from(val: Boolean) -> Self {
53        val.0
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60    use smb_tests::*;
61
62    test_binrw! {
63        Boolean => true: Boolean::from(true) => "01"
64    }
65
66    test_binrw! {
67        Boolean => false: Boolean::from(false) => "00"
68    }
69
70    // Non-zero is considered true!
71    test_binrw_read! {
72        Boolean => true_non_zero: Boolean::from(true) => "17"
73    }
74}