1use crate::Direction;
7use rstm_state::{RawState, State};
8
9pub type TailRef<'a, Q, A> = Tail<&'a Q, &'a A>;
11pub type TailMut<'a, Q, A> = Tail<&'a mut Q, &'a mut A>;
13#[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Ord, PartialOrd)]
16#[cfg_attr(
17 feature = "serde",
18 derive(serde::Deserialize, serde::Serialize),
19 serde(deny_unknown_fields, rename_all = "snake_case")
20)]
21#[repr(C)]
22pub struct Tail<Q, A> {
23 #[cfg_attr(feature = "serde", serde(alias = "move_direction", alias = "dir"))]
25 pub direction: Direction,
26 #[cfg_attr(feature = "serde", serde(alias = "write_state"))]
27 pub next_state: State<Q>,
28 #[cfg_attr(feature = "serde", serde(alias = "next_symbol"))]
29 pub write_symbol: A,
30}
31pub trait RawTail {
34 type State: RawState;
35 type Symbol;
36 private! {}
37 fn direction(&self) -> Direction;
39 fn next_state(&self) -> &State<Self::State>;
41 fn write_symbol(&self) -> &Self::Symbol;
43}
44pub trait RawTailMut: RawTail {
46 fn direction_mut(&mut self) -> &mut Direction;
48 fn next_state_mut(&mut self) -> &mut State<Self::State>;
50 fn write_symbol_mut(&mut self) -> &mut Self::Symbol;
52}
53pub trait TailRepr: RawTail + Sized {
55 fn new(direction: Direction, next_state: Self::State, write_symbol: Self::Symbol) -> Self;
57 fn right(next_state: Self::State, write_symbol: Self::Symbol) -> Self {
60 Self::new(Direction::Right, next_state, write_symbol)
61 }
62 fn left(next_state: Self::State, write_symbol: Self::Symbol) -> Self {
65 Self::new(Direction::Left, next_state, write_symbol)
66 }
67 fn stay(next_state: Self::State, write_symbol: Self::Symbol) -> Self {
68 Self::new(Direction::Stay, next_state, write_symbol)
69 }
70}
71impl<Q, A> RawTail for (Direction, State<Q>, A)
75where
76 Q: RawState,
77{
78 type State = Q;
79 type Symbol = A;
80
81 seal! {}
82 fn direction(&self) -> Direction {
84 self.0
85 }
86 fn next_state(&self) -> &State<Q> {
88 &self.1
89 }
90 fn write_symbol(&self) -> &A {
92 &self.2
93 }
94}
95
96impl<Q, A> RawTailMut for (Direction, State<Q>, A)
97where
98 Q: RawState,
99{
100 fn direction_mut(&mut self) -> &mut Direction {
102 &mut self.0
103 }
104 fn next_state_mut(&mut self) -> &mut State<Q> {
106 &mut self.1
107 }
108 fn write_symbol_mut(&mut self) -> &mut A {
110 &mut self.2
111 }
112}
113
114impl<Q, A> TailRepr for (Direction, State<Q>, A)
115where
116 Q: RawState,
117{
118 fn new(direction: Direction, next_state: Q, write_symbol: A) -> Self {
120 (direction, State(next_state), write_symbol)
121 }
122}
123
124impl<Q, A> RawTail for Tail<Q, A>
125where
126 Q: RawState,
127{
128 type State = Q;
129 type Symbol = A;
130
131 seal! {}
132 fn direction(&self) -> Direction {
134 self.direction
135 }
136 fn next_state(&self) -> &State<Q> {
138 &self.next_state
139 }
140 fn write_symbol(&self) -> &A {
142 &self.write_symbol
143 }
144}
145impl<Q, A> RawTailMut for Tail<Q, A>
146where
147 Q: RawState,
148{
149 fn direction_mut(&mut self) -> &mut Direction {
151 &mut self.direction
152 }
153 fn next_state_mut(&mut self) -> &mut State<Q> {
155 &mut self.next_state
156 }
157 fn write_symbol_mut(&mut self) -> &mut A {
159 &mut self.write_symbol
160 }
161}
162
163impl<Q, A> TailRepr for Tail<Q, A>
164where
165 Q: RawState,
166{
167 fn new(direction: Direction, next_state: Q, write_symbol: A) -> Self {
169 Self {
170 direction,
171 next_state: State(next_state),
172 write_symbol,
173 }
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use super::*;
180
181 #[test]
182 fn test_tail_init() {
183 let tail: Tail<&str, char> = Tail::right("q1", 'a');
184 assert_eq! {
185 tail,
186 (
187 Direction::Right,
188 State("q1"),
189 'a'
190 )
191 }
192 }
193}