aboutsummaryrefslogtreecommitdiff
path: root/examples/custom_bits_type.rs
blob: 8924bfdf31a6e4cb6c8305b370fec3ec79b1e6c1 (plain)
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
use std::ops::{BitAnd, BitOr, BitXor, Not};

use bitflags::{Bits, Flag, Flags};

// Define a custom container that can be used in flags types
// Note custom bits types can't be used in `bitflags!`
// without making the trait impls `const`. This is currently
// unstable
#[derive(Clone, Copy, Debug)]
pub struct CustomBits([bool; 3]);

impl Bits for CustomBits {
    const EMPTY: Self = CustomBits([false; 3]);

    const ALL: Self = CustomBits([true; 3]);
}

impl PartialEq for CustomBits {
    fn eq(&self, other: &Self) -> bool {
        self.0 == other.0
    }
}

impl BitAnd for CustomBits {
    type Output = Self;

    fn bitand(self, other: Self) -> Self {
        CustomBits([
            self.0[0] & other.0[0],
            self.0[1] & other.0[1],
            self.0[2] & other.0[2],
        ])
    }
}

impl BitOr for CustomBits {
    type Output = Self;

    fn bitor(self, other: Self) -> Self {
        CustomBits([
            self.0[0] | other.0[0],
            self.0[1] | other.0[1],
            self.0[2] | other.0[2],
        ])
    }
}

impl BitXor for CustomBits {
    type Output = Self;

    fn bitxor(self, other: Self) -> Self {
        CustomBits([
            self.0[0] & other.0[0],
            self.0[1] & other.0[1],
            self.0[2] & other.0[2],
        ])
    }
}

impl Not for CustomBits {
    type Output = Self;

    fn not(self) -> Self {
        CustomBits([!self.0[0], !self.0[1], !self.0[2]])
    }
}

#[derive(Clone, Copy, Debug)]
pub struct CustomFlags(CustomBits);

impl CustomFlags {
    pub const A: Self = CustomFlags(CustomBits([true, false, false]));
    pub const B: Self = CustomFlags(CustomBits([false, true, false]));
    pub const C: Self = CustomFlags(CustomBits([false, false, true]));
}

impl Flags for CustomFlags {
    const FLAGS: &'static [Flag<Self>] = &[
        Flag::new("A", Self::A),
        Flag::new("B", Self::B),
        Flag::new("C", Self::C),
    ];

    type Bits = CustomBits;

    fn bits(&self) -> Self::Bits {
        self.0
    }

    fn from_bits_retain(bits: Self::Bits) -> Self {
        CustomFlags(bits)
    }
}

fn main() {
    println!("{:?}", CustomFlags::A.union(CustomFlags::C));
}