ab_io_type/
bool.rs

1use crate::metadata::IoTypeMetadataKind;
2use crate::trivial_type::TrivialType;
3use core::ops::Not;
4
5/// Just like `bool`, but any bit pattern is valid.
6///
7/// For `bool` only `0` and `1` are valid bit patterns out of 256 possible, anything else is
8/// undefined behavior. This type changes that by treating `0` as `false` and everything else as
9/// `true`, making it safer to use and allowing it to implement `TrivialType`.
10#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
11#[repr(C)]
12pub struct Bool {
13    byte: u8,
14}
15
16impl Not for Bool {
17    type Output = Self;
18
19    #[inline(always)]
20    fn not(self) -> Self::Output {
21        Self {
22            byte: (self.byte == 0) as u8,
23        }
24    }
25}
26
27impl From<bool> for Bool {
28    #[inline(always)]
29    fn from(value: bool) -> Self {
30        Self::new(value)
31    }
32}
33
34impl From<Bool> for bool {
35    #[inline(always)]
36    fn from(value: Bool) -> Self {
37        value.get()
38    }
39}
40
41// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
42unsafe impl TrivialType for Bool {
43    const METADATA: &[u8] = &[IoTypeMetadataKind::Bool as u8];
44}
45
46impl Bool {
47    /// Create a new instance from existing boolean value
48    #[inline(always)]
49    pub const fn new(value: bool) -> Self {
50        Self { byte: value as u8 }
51    }
52
53    /// Get the value
54    #[inline(always)]
55    pub const fn get(&self) -> bool {
56        self.byte != 0
57    }
58
59    /// Set new value
60    #[inline(always)]
61    pub const fn set(&mut self, value: bool) {
62        self.byte = value as u8;
63    }
64}