eryon_core/types/
head.rs

1/*
2    Appellation: head <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use crate::Direction;
6use crate::state::{RawState, State};
7
8/// The [Head] is formally defined to be a 2-tuple consisting of a state / symbol pair.
9#[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Ord, PartialOrd)]
10#[cfg_attr(
11    feature = "serde",
12    derive(serde::Deserialize, serde::Serialize),
13    serde(rename_all = "lowercase")
14)]
15#[repr(C)]
16pub struct Head<Q, S> {
17    #[cfg_attr(feature = "serde", serde(alias = "current_state"))]
18    pub state: State<Q>,
19    #[cfg_attr(feature = "serde", serde(alias = "current_symbol"))]
20    pub symbol: S,
21}
22
23impl<Q, S> Head<Q, S>
24where
25    Q: RawState,
26{
27    pub const fn new(state: State<Q>, symbol: S) -> Self {
28        Self { state, symbol }
29    }
30    /// Create a new instance of the [Head] using the given state and default symbol.
31    pub fn from_state(state: State<Q>) -> Self
32    where
33        S: Default,
34    {
35        Self::new(state, S::default())
36    }
37    /// Create a new instance of the [Head] using the given symbol and default state.
38    pub fn from_symbol(symbol: S) -> Self
39    where
40        Q: Default,
41    {
42        Self::new(State::default(), symbol)
43    }
44    /// Create a new instance from a 2-tuple: ([state](State), symbol)
45    pub fn from_tuple((state, symbol): (State<Q>, S)) -> Self {
46        Self { state, symbol }
47    }
48    /// Updates the current [state](State) and returns a new head
49    pub fn with_state(self, state: State<Q>) -> Self {
50        Self { state, ..self }
51    }
52    /// Updates the current symbol and returns a new head
53    pub fn with_symbol(self, symbol: S) -> Self {
54        Self { symbol, ..self }
55    }
56    /// Returns a reference to the current state
57    pub const fn state(&self) -> &State<Q> {
58        &self.state
59    }
60    /// Returns a mutable reference to the current [State]
61    pub const fn state_mut(&mut self) -> &mut State<Q> {
62        &mut self.state
63    }
64    /// Returns a reference to the current symbol
65    pub const fn symbol(&self) -> &S {
66        &self.symbol
67    }
68    /// Returns a mutable reference to the current symbol
69    pub const fn symbol_mut(&mut self) -> &mut S {
70        &mut self.symbol
71    }
72    /// Returns a reference to the current state and symbol returing a 2-tuple
73    pub fn as_tuple(&self) -> (&State<Q>, &S) {
74        (&self.state, &self.symbol)
75    }
76    /// Consumes the head and returns the current state and symbol as a 2-tuple
77    pub fn into_tuple(self) -> (State<Q>, S) {
78        (self.state, self.symbol)
79    }
80    /// Returns a mutable reference to the current state and symbol as a 2-tuple
81    pub fn as_mut_tuple(&mut self) -> (&mut State<Q>, &mut S) {
82        (&mut self.state, &mut self.symbol)
83    }
84    /// Updates the current state
85    pub fn set_state(&mut self, State(state): State<Q>) -> &mut Self {
86        self.state_mut().set(state);
87        self
88    }
89    /// Updates the current symbol
90    pub fn set_symbol(&mut self, symbol: S) -> &mut Self {
91        self.symbol = symbol;
92        self
93    }
94    /// Replaces the current state and symbol with the given state and symbol; returns the
95    /// previous instance of the head.
96    pub fn replace(&mut self, state: State<Q>, symbol: S) -> Self {
97        Head {
98            state: self.replace_state(state),
99            symbol: self.replace_symbol(symbol),
100        }
101    }
102    /// [`replace`](core::mem::replace) the current state with the given state, returning the
103    /// previous state
104    pub const fn replace_state(&mut self, state: State<Q>) -> State<Q> {
105        core::mem::replace(self.state_mut(), state)
106    }
107    /// [`replace`](core::mem::replace) the current symbol with the given symbol, returning the
108    /// previous symbol
109    pub const fn replace_symbol(&mut self, symbol: S) -> S {
110        core::mem::replace(self.symbol_mut(), symbol)
111    }
112    /// [`swap`](core::mem::swap) the current state and symbol with those of the given head
113    pub const fn swap(&mut self, other: &mut Self) {
114        // swap the states
115        core::mem::swap(self.state_mut(), other.state_mut());
116        // swap the symbols
117        core::mem::swap(self.symbol_mut(), other.symbol_mut());
118    }
119    /// Updates the current [State] and symbol
120    pub fn update(&mut self, state: Option<State<Q>>, symbol: Option<S>) {
121        if let Some(state) = state {
122            self.state = state;
123        }
124        if let Some(symbol) = symbol {
125            self.symbol = symbol;
126        }
127    }
128
129    /// returns a new head with immutable references to the current state and symbol
130    pub const fn view(&self) -> Head<&Q, &S> {
131        Head {
132            state: self.state().view(),
133            symbol: self.symbol(),
134        }
135    }
136    /// returns a new head with mutable references to the current state and symbol
137    pub fn view_mut(&mut self) -> Head<&mut Q, &mut S> {
138        Head {
139            state: self.state.view_mut(),
140            symbol: &mut self.symbol,
141        }
142    }
143    /// tries reading the given tape using the head as its coordinates.
144    pub fn read<T>(self, tape: &'_ [T]) -> Option<&<S>::Output>
145    where
146        S: core::slice::SliceIndex<[T]>,
147    {
148        tape.get(self.symbol)
149    }
150    #[deprecated(
151        since = "0.0.7",
152        note = "use `view` instead, as it is more idiomatic and clearer."
153    )]
154    pub fn to_ref(&self) -> Head<&Q, &S> {
155        Head {
156            state: self.state.view(),
157            symbol: &self.symbol,
158        }
159    }
160    #[deprecated(
161        since = "0.0.7",
162        note = "use `view_mut` instead, as it is more idiomatic and clearer."
163    )]
164    pub fn to_mut(&mut self) -> Head<&mut Q, &mut S> {
165        self.view_mut()
166    }
167}
168
169impl<'a, Q, S> Head<&'a Q, &'a S>
170where
171    Q: RawState,
172{
173    /// returns a new [`Head`] with cloned elements
174    pub fn cloned(&self) -> Head<Q, S>
175    where
176        Q: Clone,
177        S: Clone,
178    {
179        Head {
180            state: self.state.cloned(),
181            symbol: self.symbol.clone(),
182        }
183    }
184    /// returns a new [`Head`] with copied elements
185    pub fn copied(&self) -> Head<Q, S>
186    where
187        Q: Copy,
188        S: Copy,
189    {
190        Head {
191            state: self.state.copied(),
192            symbol: *self.symbol,
193        }
194    }
195}
196
197impl<'a, Q, S> Head<&'a mut Q, &'a mut S>
198where
199    Q: RawState,
200{
201    /// returns a new [`Head`] with cloned elements
202    pub fn cloned(&self) -> Head<Q, S>
203    where
204        Q: Clone,
205        S: Clone,
206    {
207        Head {
208            state: self.state.cloned(),
209            symbol: self.symbol.clone(),
210        }
211    }
212    /// returns a new [`Head`] with copied elements
213    pub fn copied(&self) -> Head<Q, S>
214    where
215        Q: Copy,
216        S: Copy,
217    {
218        Head {
219            state: self.state.copied(),
220            symbol: *self.symbol,
221        }
222    }
223}
224
225impl<Q> Head<Q, usize>
226where
227    Q: RawState,
228{
229    pub fn shift(self, direction: Direction) -> Self {
230        Self {
231            symbol: direction.apply_unsigned(self.symbol),
232            ..self
233        }
234    }
235
236    pub fn shift_inplace(&mut self, direction: Direction) {
237        self.symbol = direction.apply_unsigned(self.symbol);
238    }
239}
240
241impl<Q, S> core::fmt::Debug for Head<Q, S>
242where
243    Q: RawState,
244    S: core::fmt::Debug,
245{
246    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
247        f.debug_tuple("Head")
248            .field(&self.state)
249            .field(&self.symbol)
250            .finish()
251    }
252}
253
254impl<Q, S> core::fmt::Display for Head<Q, S>
255where
256    Q: RawState,
257    S: core::fmt::Display,
258{
259    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
260        write!(f, "{{ state: {}, symbol: {} }}", self.state, self.symbol)
261    }
262}
263
264impl<Q, S> PartialEq<State<Q>> for Head<Q, S>
265where
266    Q: RawState + PartialEq,
267{
268    fn eq(&self, state: &State<Q>) -> bool {
269        self.state() == state
270    }
271}
272
273impl<Q, S> PartialEq<Head<Q, S>> for State<Q>
274where
275    Q: RawState + PartialEq,
276{
277    fn eq(&self, head: &Head<Q, S>) -> bool {
278        self == head.state()
279    }
280}
281
282impl<Q, S> PartialEq<Head<Q, S>> for State<&Q>
283where
284    Q: RawState + PartialEq,
285{
286    fn eq(&self, head: &Head<Q, S>) -> bool {
287        *self == head.state().view()
288    }
289}
290
291impl<'a, Q, S> PartialEq<State<&'a Q>> for Head<Q, S>
292where
293    Q: RawState + PartialEq,
294{
295    fn eq(&self, state: &State<&'a Q>) -> bool {
296        self.state().view() == *state
297    }
298}
299
300impl<Q, S> PartialEq<(State<Q>, S)> for Head<Q, S>
301where
302    Q: RawState + PartialEq,
303    S: PartialEq,
304{
305    fn eq(&self, (state, symbol): &(State<Q>, S)) -> bool {
306        &self.state == state && &self.symbol == symbol
307    }
308}
309
310impl<Q, S> PartialEq<(Q, S)> for Head<Q, S>
311where
312    State<Q>: PartialEq,
313    Q: RawState + PartialEq,
314    S: PartialEq,
315{
316    fn eq(&self, (state, symbol): &(Q, S)) -> bool {
317        self.state() == state && self.symbol() == symbol
318    }
319}
320
321impl<Q, S> PartialEq<Head<Q, S>> for (State<Q>, S)
322where
323    Q: RawState + PartialEq,
324    S: PartialEq,
325{
326    fn eq(&self, head: &Head<Q, S>) -> bool {
327        head.state() == &self.0 && head.symbol() == &self.1
328    }
329}
330
331impl<Q, S> From<(Q, S)> for Head<Q, S>
332where
333    Q: RawState,
334{
335    fn from((state, symbol): (Q, S)) -> Self {
336        Self::new(State(state), symbol)
337    }
338}
339
340impl<Q, S> From<(State<Q>, S)> for Head<Q, S>
341where
342    Q: RawState,
343{
344    fn from((state, symbol): (State<Q>, S)) -> Self {
345        Self::new(state, symbol)
346    }
347}
348
349impl<Q, S> From<Head<Q, S>> for (State<Q>, S)
350where
351    Q: RawState,
352{
353    fn from(head: Head<Q, S>) -> Self {
354        head.into_tuple()
355    }
356}