joydev/event_codes/
mod.rs

1//! Event codes sent by devices
2//!
3//! Those codes are used for axis and button mapping.
4
5use std::fmt::Debug;
6use std::hash::Hash;
7use std::ops::AddAssign;
8
9pub use self::absolute_axis::AbsoluteAxis;
10pub use self::key::Key;
11use std::marker::PhantomData;
12
13mod absolute_axis;
14mod key;
15
16/// Trait common to all event codes
17pub trait EventCode<T>
18where
19	Self: Clone + Copy + Debug + Default + Eq + Hash + Sized,
20	T: EventCodeValue,
21{
22	/// Code count
23	const COUNT: T;
24	/// Maximum value
25	const MAX: T;
26
27	/// Return the default event code iterator
28	fn iter() -> IntoIter<Self, T> {
29		IntoIter {
30			phantom: PhantomData,
31			value: unsafe { *(&Self::default() as *const Self as *const T) },
32		}
33	}
34}
35
36/// Trait common to all event code values
37pub trait EventCodeValue
38where
39	Self: AddAssign + Clone + Copy + Debug + Eq + Hash + Ord + Sized,
40{
41	/// Value of one
42	const ONE: Self;
43}
44
45impl EventCodeValue for u8 {
46	const ONE: Self = 1u8;
47}
48
49impl EventCodeValue for u16 {
50	const ONE: Self = 1u16;
51}
52
53/// Event code iterator
54pub struct IntoIter<T, U>
55where
56	T: EventCode<U>,
57	U: EventCodeValue,
58{
59	pub(crate) phantom: std::marker::PhantomData<T>,
60	pub(crate) value: U,
61}
62
63impl<T, U> Iterator for IntoIter<T, U>
64where
65	T: EventCode<U>,
66	U: EventCodeValue,
67{
68	type Item = T;
69
70	fn next(&mut self) -> Option<Self::Item> {
71		if self.value >= T::MAX {
72			None
73		} else {
74			let result = Some(unsafe { *(&self.value as *const U as *const T) });
75			self.value += U::ONE;
76			result
77		}
78	}
79}