smart_keymap/
tuples.rs

1use core::fmt::Debug;
2use core::ops::Index;
3
4use crate::key;
5
6/// A tuple struct for 1 key.
7#[derive(Debug)]
8pub struct Keys1<
9    K0: key::Key<Context = Ctx, Event = Ev, PendingKeyState = PKS, KeyState = KS>,
10    Ctx,
11    Ev,
12    PKS,
13    KS,
14    const M: usize = { crate::key::MAX_KEY_EVENTS },
15>(K0);
16
17impl<
18        K0: key::Key<Context = Ctx, Event = Ev, PendingKeyState = PKS, KeyState = KS> + Copy,
19        Ctx,
20        Ev,
21        PKS,
22        KS,
23        const M: usize,
24    > Keys1<K0, Ctx, Ev, PKS, KS, M>
25{
26    /// Constructs a KeysN for the given tuple.
27    pub const fn new((k0,): (K0,)) -> Self {
28        Keys1(k0)
29    }
30}
31
32impl<
33        K0: key::Key<Context = Ctx, Event = Ev, PendingKeyState = PKS, KeyState = KS> + 'static,
34        Ctx,
35        Ev,
36        PKS,
37        KS,
38        const M: usize,
39    > Index<usize> for Keys1<K0, Ctx, Ev, PKS, KS, M>
40{
41    type Output = dyn key::Key<Context = Ctx, Event = Ev, PendingKeyState = PKS, KeyState = KS>;
42
43    fn index(&self, idx: usize) -> &Self::Output {
44        match idx {
45            0 => &self.0,
46            _ => panic!("Index out of bounds"),
47        }
48    }
49}
50
51// Use seq_macro's seq! to generate Keys2, Keys3, etc.
52
53macro_rules! define_keys {
54    ($n:expr) => {
55        paste::paste! {
56            seq_macro::seq!(I in 0..$n {
57                /// A tuple struct for some number of keys.
58                #[derive(core::fmt::Debug)]
59                pub struct [<Keys $n>]<
60                    #(
61                        K~I: crate::key::Key<Context = Ctx, Event = Ev, PendingKeyState = PKS, KeyState = KS>,
62                    )*
63                    Ctx,
64                    Ev,
65                    PKS,
66                    KS,
67                    const M: usize = { crate::key::MAX_KEY_EVENTS },
68                >(
69                    #(
70                        K~I,
71                    )*
72                );
73
74                impl<
75                    #(
76                        K~I: crate::key::Key<Context = Ctx, Event = Ev, PendingKeyState = PKS, KeyState = KS> + Copy,
77                    )*
78                    Ctx,
79                    Ev,
80                    PKS,
81                    KS,
82                    const M: usize,
83                > [<Keys $n>]<
84                    #(K~I,)*
85                    Ctx, Ev, PKS, KS, M
86                >
87                {
88                    /// Constructs a KeysN tuple struct with the given tuple.
89                    pub const fn new((
90                        #(k~I,)*
91                    ): (
92                        #(K~I,)*
93                    )) -> Self {
94                        [<Keys $n>](
95                            #(
96                                (k~I),
97                            )*
98                        )
99                    }
100                }
101
102                impl<
103                    #(
104                        K~I: crate::key::Key<Context = Ctx, Event = Ev, PendingKeyState = PKS, KeyState = KS> + 'static,
105                    )*
106                    Ctx,
107                    Ev,
108                    PKS,
109                    KS,
110                    const M: usize,
111                > core::ops::Index<usize> for [<Keys $n>]<
112                    #(K~I,)*
113                    Ctx, Ev, PKS, KS, M
114                    >
115                {
116                    type Output = dyn crate::key::Key<Context = Ctx, Event = Ev, PendingKeyState = PKS, KeyState = KS>;
117
118                    fn index(&self, idx: usize) -> &Self::Output {
119                        match idx {
120                            #(
121                                I => &self.I,
122                            )*
123                            _ => panic!("Index out of bounds"),
124                        }
125                    }
126                }
127            });
128        }
129    };
130}
131
132pub(crate) use define_keys;
133
134define_keys!(2);
135
136define_keys!(4);