sweetacid_evdev/
attribute_set.rs

1use bitvec::prelude::*;
2use std::fmt;
3use std::ops::{Deref, DerefMut};
4
5/// A collection of bits representing either device capability or state.
6///
7/// This can be used to iterate across all keys supported by a keyboard, or all buttons supported
8/// by a joystick. You can also query directly whether a specific bit is set (corresponding to
9/// whether a key or button is depressed).
10#[repr(transparent)]
11pub struct AttributeSetRef<T> {
12    _indexer: std::marker::PhantomData<T>,
13    bitslice: BitSlice<Lsb0, u8>,
14}
15
16impl<T: EvdevEnum> AttributeSetRef<T> {
17    #[inline]
18    fn new(bitslice: &BitSlice<Lsb0, u8>) -> &Self {
19        // SAFETY: for<T> AttributeSet<T> is repr(transparent) over BitSlice<Lsb0, u8>
20        unsafe { &*(bitslice as *const BitSlice<Lsb0, u8> as *const Self) }
21    }
22
23    #[inline]
24    fn new_mut(bitslice: &mut BitSlice<Lsb0, u8>) -> &mut Self {
25        // SAFETY: for<T> AttributeSet<T> is repr(transparent) over BitSlice<Lsb0, u8>
26        unsafe { &mut *(bitslice as *mut BitSlice<Lsb0, u8> as *mut Self) }
27    }
28
29    /// Returns `true` if this AttributeSet contains the passed T.
30    #[inline]
31    pub fn contains(&self, attr: T) -> bool {
32        self.bitslice.get(attr.to_index()).map_or(false, |b| *b)
33    }
34
35    /// Provides an iterator over all "set" bits in the collection.
36    #[inline]
37    pub fn iter(&self) -> impl Iterator<Item = T> + '_ {
38        self.bitslice.iter_ones().map(T::from_index)
39    }
40
41    #[inline]
42    pub(crate) fn slice(&self, start: T) -> &Self {
43        Self::new(&self.bitslice[start.to_index()..])
44    }
45
46    pub fn insert(&mut self, attr: T) {
47        self.set(attr, true)
48    }
49
50    pub fn remove(&mut self, attr: T) {
51        self.set(attr, false)
52    }
53
54    // TODO: figure out a good name for this if we make it public
55    #[inline]
56    pub(crate) fn set(&mut self, attr: T, on: bool) {
57        self.bitslice.set(attr.to_index(), on)
58    }
59}
60
61impl<T: EvdevEnum + fmt::Debug> fmt::Debug for AttributeSetRef<T> {
62    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63        f.debug_set().entries(self.iter()).finish()
64    }
65}
66
67pub struct AttributeSet<T: ArrayedEvdevEnum> {
68    container: T::Array,
69}
70
71impl<T: ArrayedEvdevEnum> AttributeSet<T> {
72    pub fn new() -> Self {
73        Self {
74            container: T::zeroed_array(),
75        }
76    }
77
78    fn as_bitslice(&self) -> &BitSlice<Lsb0, u8> {
79        T::array_as_slice(&self.container)
80    }
81
82    fn as_mut_bitslice(&mut self) -> &mut BitSlice<Lsb0, u8> {
83        T::array_as_slice_mut(&mut self.container)
84    }
85
86    #[inline]
87    pub(crate) fn as_mut_raw_slice(&mut self) -> &mut [u8] {
88        T::array_as_buf(&mut self.container)
89    }
90}
91
92impl<T: ArrayedEvdevEnum> Default for AttributeSet<T> {
93    fn default() -> Self {
94        Self::new()
95    }
96}
97
98impl<T: ArrayedEvdevEnum> Deref for AttributeSet<T> {
99    type Target = AttributeSetRef<T>;
100    fn deref(&self) -> &AttributeSetRef<T> {
101        AttributeSetRef::new(self.as_bitslice())
102    }
103}
104
105impl<T: ArrayedEvdevEnum> DerefMut for AttributeSet<T> {
106    fn deref_mut(&mut self) -> &mut AttributeSetRef<T> {
107        AttributeSetRef::new_mut(self.as_mut_bitslice())
108    }
109}
110
111impl<T: ArrayedEvdevEnum> Clone for AttributeSet<T>
112where
113    T::Array: Clone,
114{
115    fn clone(&self) -> Self {
116        Self {
117            container: self.container.clone(),
118        }
119    }
120    fn clone_from(&mut self, other: &Self) {
121        self.container.clone_from(&other.container)
122    }
123}
124
125impl<T: ArrayedEvdevEnum + fmt::Debug> fmt::Debug for AttributeSet<T> {
126    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
127        (**self).fmt(f)
128    }
129}
130
131pub trait EvdevEnum: Copy + 'static {
132    fn from_index(i: usize) -> Self;
133    fn to_index(self) -> usize;
134}
135
136pub trait ArrayedEvdevEnum: EvdevEnum {
137    type Array;
138    fn array_as_slice(arr: &Self::Array) -> &BitSlice<Lsb0, u8>;
139    fn array_as_slice_mut(arr: &mut Self::Array) -> &mut BitSlice<Lsb0, u8>;
140    fn array_as_buf(arr: &mut Self::Array) -> &mut [u8];
141    fn zeroed_array() -> Self::Array;
142}
143
144macro_rules! evdev_enum {
145    ($t:ty, Array, $($(#[$attr:meta])* $c:ident = $val:expr,)*) => {
146        evdev_enum!(
147            $t,
148            Array:bitvec::BitArr!(for <$t>::COUNT, in u8),
149            |x| x,
150            |x| x,
151            bitvec::array::BitArray::as_mut_raw_slice,
152            bitvec::array::BitArray::zeroed,
153            $($(#[$attr])* $c = $val,)*
154        );
155    };
156    (
157        $t:ty,
158        Array: $Array:ty, $arr_as_slice:expr, $arr_as_slice_mut:expr, $arr_as_buf:expr, $zero:expr,
159        $($(#[$attr:meta])* $c:ident = $val:expr,)*
160    ) => {
161        impl $crate::attribute_set::ArrayedEvdevEnum for $t {
162            type Array = $Array;
163            fn array_as_slice(arr: &Self::Array) -> &bitvec::slice::BitSlice<bitvec::order::Lsb0, u8> {
164                let f: fn(&Self::Array) -> &bitvec::slice::BitSlice<bitvec::order::Lsb0, u8> = $arr_as_slice;
165                f(arr)
166            }
167            fn array_as_slice_mut(arr: &mut Self::Array) -> &mut bitvec::slice::BitSlice<bitvec::order::Lsb0, u8> {
168                let f: fn(&mut Self::Array) -> &mut bitvec::slice::BitSlice<bitvec::order::Lsb0, u8> = $arr_as_slice_mut;
169                f(arr)
170            }
171            fn array_as_buf(arr: &mut Self::Array) -> &mut [u8] {
172                let f: fn(&mut Self::Array) -> &mut [u8] = $arr_as_buf;
173                f(arr)
174            }
175            fn zeroed_array() -> Self::Array {
176                $zero()
177            }
178        }
179        evdev_enum!($t, $($(#[$attr])* $c = $val,)*);
180    };
181    ($t:ty, $($(#[$attr:meta])* $c:ident = $val:expr,)*) => {
182        impl $t {
183            $($(#[$attr])* pub const $c: Self = Self($val);)*
184        }
185        impl std::str::FromStr for $t {
186            type Err = crate::EnumParseError;
187
188            fn from_str(s: &str) ->  Result<Self, Self::Err> {
189                let map: &[(&'static str, $t)] = &[
190                    $((stringify!($c), Self::$c),)*
191                ];
192
193                match map.iter().find(|e| e.0 == s) {
194                    Some(e) => Ok(e.1),
195                    None => Err(crate::EnumParseError(())),
196                }
197            }
198        }
199        impl std::fmt::Debug for $t {
200            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
201                #[allow(unreachable_patterns)]
202                match *self {
203                    $(Self::$c => f.pad(stringify!($c)),)*
204                    _ => write!(f, "unknown key: {}", self.0),
205                }
206            }
207        }
208        impl $crate::attribute_set::EvdevEnum for $t {
209            #[inline]
210            fn from_index(i: usize) -> Self {
211                Self(i as _)
212            }
213            #[inline]
214            fn to_index(self) -> usize {
215                self.0 as _
216            }
217        }
218    }
219}