sweetacid_evdev/
attribute_set.rs1use bitvec::prelude::*;
2use std::fmt;
3use std::ops::{Deref, DerefMut};
4
5#[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 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 unsafe { &mut *(bitslice as *mut BitSlice<Lsb0, u8> as *mut Self) }
27 }
28
29 #[inline]
31 pub fn contains(&self, attr: T) -> bool {
32 self.bitslice.get(attr.to_index()).map_or(false, |b| *b)
33 }
34
35 #[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 #[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}