heavy_duty_bools/
lib.rs

1// lib.rs
2
3#![doc = include_str!("../README.md")]
4
5//! # HDBool
6//! 
7//! Check out the [HDBool] struct for more information.
8//! 
9
10#[derive(Clone, Copy, Debug, PartialEq)]
11pub struct HDBool(u8);
12
13impl HDBool {
14    /// Creates an `HDBool` from a normal bool.
15    pub fn new(val: bool) -> Self {
16        HDBool(if val { u8::MAX } else { u8::MIN })
17    }
18
19    /// Creates an `HDBool` from a raw `u8`, refreshing it if it's imperfect.
20    pub fn from_u8(raw: u8) -> Self {
21        HDBool(Self::refresh(raw))
22    }
23
24    /// Extracts the raw `u8` representation (all 1s or all 0s after refresh).
25    pub fn as_u8(&self) -> u8 {
26        self.0
27    }
28
29    /// Returns the normal bool form.
30    pub fn to_bool(&self) -> bool {
31        // any value other than 0xFF or 0x00 is first corrected
32        match self.0 {
33            0xFF => true,
34            0x00 => false,
35            _ => HDBool::refresh(self.0) == u8::MAX,
36        }
37    }
38
39    /// Refresh a raw `u8` into either 0xFF or 0x00.
40    fn refresh(raw: u8) -> u8 {
41        if raw.count_ones() > 4 {
42            u8::MAX
43        } else {
44            u8::MIN
45        }
46    }
47}
48
49
50#[cfg(test)]
51mod tests {
52    use std::u8;
53
54    use super::*;
55
56    #[test]
57    fn test_normal_bool_representation() {
58        assert_eq!(true as u8, 0b_0000_0001_u8);
59        assert_eq!(false as u8, 0b_0000_0000_u8);
60        assert_ne!(true as u8, 0b_1111_1111_u8);
61        assert_ne!(false as u8, 0b_1000_0000_u8);
62        assert_ne!(true as u8, 0b_0100_0010_u8);
63        assert_ne!(false as u8, 0b_0010_0001_u8);
64
65        assert_ne!(true as u8, HDBool::new(true).as_u8());
66        assert_ne!(false as u8, HDBool::new(true).as_u8());
67        assert_ne!(true as u8, HDBool::new(false).as_u8());
68        assert_eq!(false as u8, HDBool::new(false).as_u8());
69
70        assert!(true);
71        assert!(!false);
72    }
73
74    #[test]
75    fn test_hdbool() {
76        assert_eq!(HDBool::new(true), HDBool(u8::MAX));
77        assert_eq!(HDBool::new(false), HDBool(u8::MIN));
78        assert_eq!(HDBool::new(true).to_bool(), true);
79        assert_eq!(HDBool::new(false).to_bool(), false);
80        assert_eq!(HDBool::new(true).as_u8(), u8::MAX);
81        assert_eq!(HDBool::new(false).as_u8(), u8::MIN);
82
83        assert_eq!(HDBool::from_u8(0b_1111_1111_u8), HDBool(u8::MAX));
84        assert_eq!(HDBool::from_u8(0b_0000_0000_u8), HDBool(u8::MIN));
85        assert_eq!(HDBool::from_u8(0b_1111_1111_u8).to_bool(), true);
86        assert_eq!(HDBool::from_u8(0b_0000_0000_u8).to_bool(), false);
87        assert_eq!(HDBool::from_u8(0b_1111_1111_u8).as_u8(), u8::MAX);
88        assert_eq!(HDBool::from_u8(0b_0000_0000_u8).as_u8(), u8::MIN);
89        assert_eq!(HDBool::from_u8(0b_1111_1110_u8).to_bool(), true);
90        assert_eq!(HDBool::from_u8(0b_0000_0001_u8).to_bool(), false);
91
92        assert_eq!(HDBool(u8::MAX).as_u8(), 0b_1111_1111_u8);
93        assert_eq!(HDBool(u8::MIN).as_u8(), 0b_0000_0000_u8);
94        assert_ne!(HDBool(u8::MAX).as_u8(), 0b_0000_0000_u8);
95        assert_ne!(HDBool(u8::MIN).as_u8(), 0b_1111_1111_u8);
96        assert_ne!(HDBool(u8::MAX).as_u8(), HDBool::new(false).as_u8());
97        assert_ne!(HDBool(u8::MIN).as_u8(), HDBool::new(true).as_u8());
98
99        assert!(HDBool(u8::MAX).to_bool());
100        assert!(!HDBool(u8::MIN).to_bool());
101
102        assert_eq!(HDBool(u8::MAX).to_bool(), true);
103        assert_eq!(HDBool(u8::MIN).to_bool(), false);
104        assert_ne!(HDBool(u8::MAX).to_bool(), false);
105        assert_ne!(HDBool(u8::MIN).to_bool(), true);
106        assert_eq!(HDBool(u8::MAX).as_u8(), u8::MAX);
107        assert_eq!(HDBool(u8::MIN).as_u8(), u8::MIN);
108
109        assert_ne!(HDBool(HDBool::refresh(0b_1111_1111_u8)).to_bool(), false);
110        assert_ne!(HDBool(HDBool::refresh(0b_0000_0000_u8)).to_bool(), true);
111        assert_eq!(HDBool(HDBool::refresh(0b_1111_1111_u8)).to_bool(), true);
112        assert_eq!(HDBool(HDBool::refresh(0b_0000_0000_u8)).to_bool(), false);
113        assert_eq!(HDBool(HDBool::refresh(0b_1111_1111_u8)).as_u8(), u8::MAX);
114        assert_eq!(HDBool(HDBool::refresh(0b_0000_0000_u8)).as_u8(), u8::MIN);
115        assert_eq!(HDBool(HDBool::refresh(0b_0000_1111_u8)).as_u8(), u8::MIN);
116        assert_eq!(HDBool(HDBool::refresh(0b_1111_0000_u8)).as_u8(), u8::MIN);
117        assert_eq!(HDBool(HDBool::refresh(0b_0000_1111_u8)).to_bool(), false);
118        assert_eq!(HDBool(HDBool::refresh(0b_1111_0000_u8)).to_bool(), false);
119        assert_eq!(HDBool(HDBool::refresh(0b_0100_1111_u8)).to_bool(), true);
120
121        assert_eq!(HDBool::refresh(0b_1111_1111_u8), u8::MAX);
122        assert_eq!(HDBool::refresh(0b_0000_0000_u8), u8::MIN);
123        assert_eq!(HDBool::refresh(0b_1111_1110_u8), u8::MAX);
124        assert_eq!(HDBool::refresh(0b_0000_0001_u8), u8::MIN);
125        assert_eq!(HDBool::refresh(0b_1111_1100_u8), u8::MAX);
126        assert_eq!(HDBool::refresh(0b_0000_0011_u8), u8::MIN);
127        assert_eq!(HDBool::refresh(0b_1111_1000_u8), u8::MAX);
128        assert_eq!(HDBool::refresh(0b_0000_0111_u8), u8::MIN);
129        assert_eq!(HDBool::refresh(0b_1111_0000_u8), u8::MIN);
130        assert_eq!(HDBool::refresh(0b_0000_1111_u8), u8::MIN);
131    }
132
133    #[test]
134    fn test_memory_footprint() {
135        assert_eq!(std::mem::size_of::<HDBool>(), 1);
136        assert_eq!(std::mem::size_of::<u8>(), 1);
137        assert_eq!(std::mem::size_of::<bool>(), 1);
138        assert!(std::mem::size_of::<HDBool>() <= std::mem::size_of::<u8>());
139
140        assert_eq!(std::mem::size_of_val(&HDBool::new(true)), 1);
141        assert_eq!(std::mem::size_of_val(&HDBool::new(false)), 1);
142        assert_eq!(std::mem::size_of_val(&HDBool::from_u8(0b_1111_1111_u8)), 1);
143        assert_eq!(std::mem::size_of_val(&HDBool::from_u8(0b_0000_0000_u8)), 1);
144        assert_eq!(std::mem::size_of_val(&HDBool(u8::MAX)), 1);
145        assert_eq!(std::mem::size_of_val(&HDBool(u8::MIN)), 1);
146        assert!(std::mem::size_of_val(&HDBool::new(true)) <= std::mem::size_of_val(&u8::MAX));
147    }
148
149    #[test]
150    fn test_equality_of_different_representations_for_hdbools() {
151        assert_eq!(HDBool::new(true).as_u8(), 0b_1111_1111_u8);
152        assert_eq!(HDBool::new(true).as_u8(), u8::MAX);
153        assert_eq!(HDBool::new(false).as_u8(), 0b_0000_0000_u8);
154        assert_eq!(HDBool::new(false).as_u8(), u8::MIN);
155    }
156
157}