heavy_duty_bools/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// lib.rs

#![doc = include_str!("../README.md")]

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct HDBool(u8);

impl HDBool {
    /// Creates an `HDBool` from a normal bool.
    pub fn new(val: bool) -> Self {
        HDBool(if val { u8::MAX } else { u8::MIN })
    }

    /// Creates an `HDBool` from a raw `u8`, refreshing it if it's imperfect.
    pub fn from_u8(raw: u8) -> Self {
        HDBool(Self::refresh(raw))
    }

    /// Extracts the raw `u8` representation (all 1s or all 0s after refresh).
    pub fn as_u8(&self) -> u8 {
        self.0
    }

    /// Returns the normal bool form.
    pub fn to_bool(&self) -> bool {
        // any value other than 0xFF or 0x00 is first corrected
        match self.0 {
            0xFF => true,
            0x00 => false,
            _ => HDBool::refresh(self.0) == u8::MAX,
        }
    }

    /// Refresh a raw `u8` into either 0xFF or 0x00.
    fn refresh(raw: u8) -> u8 {
        if raw.count_ones() > 4 {
            u8::MAX
        } else {
            u8::MIN
        }
    }
}


#[cfg(test)]
mod tests {
    use std::u8;

    use super::*;

    #[test]
    fn test_normal_bool_representation() {
        assert_eq!(true as u8, 0b_0000_0001_u8);
        assert_eq!(false as u8, 0b_0000_0000_u8);
        assert_ne!(true as u8, 0b_1111_1111_u8);
        assert_ne!(false as u8, 0b_1000_0000_u8);
        assert_ne!(true as u8, 0b_0100_0010_u8);
        assert_ne!(false as u8, 0b_0010_0001_u8);

        assert_ne!(true as u8, HDBool::new(true).as_u8());
        assert_ne!(false as u8, HDBool::new(true).as_u8());
        assert_ne!(true as u8, HDBool::new(false).as_u8());
        assert_eq!(false as u8, HDBool::new(false).as_u8());

        assert!(true);
        assert!(!false);
    }

    #[test]
    fn test_hdbool() {
        assert_eq!(HDBool::new(true), HDBool(u8::MAX));
        assert_eq!(HDBool::new(false), HDBool(u8::MIN));
        assert_eq!(HDBool::new(true).to_bool(), true);
        assert_eq!(HDBool::new(false).to_bool(), false);
        assert_eq!(HDBool::new(true).as_u8(), u8::MAX);
        assert_eq!(HDBool::new(false).as_u8(), u8::MIN);

        assert_eq!(HDBool::from_u8(0b_1111_1111_u8), HDBool(u8::MAX));
        assert_eq!(HDBool::from_u8(0b_0000_0000_u8), HDBool(u8::MIN));
        assert_eq!(HDBool::from_u8(0b_1111_1111_u8).to_bool(), true);
        assert_eq!(HDBool::from_u8(0b_0000_0000_u8).to_bool(), false);
        assert_eq!(HDBool::from_u8(0b_1111_1111_u8).as_u8(), u8::MAX);
        assert_eq!(HDBool::from_u8(0b_0000_0000_u8).as_u8(), u8::MIN);
        assert_eq!(HDBool::from_u8(0b_1111_1110_u8).to_bool(), true);
        assert_eq!(HDBool::from_u8(0b_0000_0001_u8).to_bool(), false);

        assert_eq!(HDBool(u8::MAX).as_u8(), 0b_1111_1111_u8);
        assert_eq!(HDBool(u8::MIN).as_u8(), 0b_0000_0000_u8);
        assert_ne!(HDBool(u8::MAX).as_u8(), 0b_0000_0000_u8);
        assert_ne!(HDBool(u8::MIN).as_u8(), 0b_1111_1111_u8);
        assert_ne!(HDBool(u8::MAX).as_u8(), HDBool::new(false).as_u8());
        assert_ne!(HDBool(u8::MIN).as_u8(), HDBool::new(true).as_u8());

        assert!(HDBool(u8::MAX).to_bool());
        assert!(!HDBool(u8::MIN).to_bool());

        assert_eq!(HDBool(u8::MAX).to_bool(), true);
        assert_eq!(HDBool(u8::MIN).to_bool(), false);
        assert_ne!(HDBool(u8::MAX).to_bool(), false);
        assert_ne!(HDBool(u8::MIN).to_bool(), true);
        assert_eq!(HDBool(u8::MAX).as_u8(), u8::MAX);
        assert_eq!(HDBool(u8::MIN).as_u8(), u8::MIN);

        assert_ne!(HDBool(HDBool::refresh(0b_1111_1111_u8)).to_bool(), false);
        assert_ne!(HDBool(HDBool::refresh(0b_0000_0000_u8)).to_bool(), true);
        assert_eq!(HDBool(HDBool::refresh(0b_1111_1111_u8)).to_bool(), true);
        assert_eq!(HDBool(HDBool::refresh(0b_0000_0000_u8)).to_bool(), false);
        assert_eq!(HDBool(HDBool::refresh(0b_1111_1111_u8)).as_u8(), u8::MAX);
        assert_eq!(HDBool(HDBool::refresh(0b_0000_0000_u8)).as_u8(), u8::MIN);
        assert_eq!(HDBool(HDBool::refresh(0b_0000_1111_u8)).as_u8(), u8::MIN);
        assert_eq!(HDBool(HDBool::refresh(0b_1111_0000_u8)).as_u8(), u8::MIN);
        assert_eq!(HDBool(HDBool::refresh(0b_0000_1111_u8)).to_bool(), false);
        assert_eq!(HDBool(HDBool::refresh(0b_1111_0000_u8)).to_bool(), false);
        assert_eq!(HDBool(HDBool::refresh(0b_0100_1111_u8)).to_bool(), true);

        assert_eq!(HDBool::refresh(0b_1111_1111_u8), u8::MAX);
        assert_eq!(HDBool::refresh(0b_0000_0000_u8), u8::MIN);
        assert_eq!(HDBool::refresh(0b_1111_1110_u8), u8::MAX);
        assert_eq!(HDBool::refresh(0b_0000_0001_u8), u8::MIN);
        assert_eq!(HDBool::refresh(0b_1111_1100_u8), u8::MAX);
        assert_eq!(HDBool::refresh(0b_0000_0011_u8), u8::MIN);
        assert_eq!(HDBool::refresh(0b_1111_1000_u8), u8::MAX);
        assert_eq!(HDBool::refresh(0b_0000_0111_u8), u8::MIN);
        assert_eq!(HDBool::refresh(0b_1111_0000_u8), u8::MIN);
        assert_eq!(HDBool::refresh(0b_0000_1111_u8), u8::MIN);


    }

    #[test]
    fn test_equality_of_different_representations_for_hdbools() {
        assert_eq!(HDBool::new(true).as_u8(), 0b_1111_1111_u8);
        assert_eq!(HDBool::new(true).as_u8(), u8::MAX);
        assert_eq!(HDBool::new(false).as_u8(), 0b_0000_0000_u8);
        assert_eq!(HDBool::new(false).as_u8(), u8::MIN);
    }

}