ab_contracts_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
41unsafe impl TrivialType for Bool {
42    const METADATA: &[u8] = &[IoTypeMetadataKind::Bool as u8];
43}
44
45impl Bool {
46    /// Create a new instance from existing boolean value
47    #[inline(always)]
48    pub const fn new(value: bool) -> Self {
49        Self { byte: value as u8 }
50    }
51
52    /// Get the value
53    #[inline(always)]
54    pub const fn get(&self) -> bool {
55        self.byte != 0
56    }
57
58    /// Set new value
59    #[inline(always)]
60    pub const fn set(&mut self, value: bool) {
61        self.byte = value as u8;
62    }
63}