Skip to main content

rstm_core/rules/impls/
impl_head.rs

1/*
2    Appellation: impl_head <module>
3    Created At: 2025.08.31:00:00:55
4    Contrib: @FL03
5*/
6use crate::motion::HeadStep;
7use crate::{Head, HeadMut, HeadRef};
8use crate::{Rule, Tail};
9use rstm_state::{RawState, State};
10
11/// The core implementation of the [`Head`] providing fundamental methods for its manipulation,
12/// including various constructors, accessors, and mutators as well as convienience methods for
13/// converting between representations.
14impl<Q, A> Head<Q, A>
15where
16    Q: RawState,
17{
18    /// initialize a new instance of the [`Head`] given some state and symbol
19    pub const fn new(state: Q, symbol: A) -> Self {
20        Self {
21            state: State(state),
22            symbol,
23        }
24    }
25    /// returns a new instance of the head using the given state and a default symbol
26    pub fn from_state(state: Q) -> Self
27    where
28        A: Default,
29    {
30        Self::new(state, <A>::default())
31    }
32    /// returns a new instance of the head using the given symbol and a default state
33    pub fn from_symbol(symbol: A) -> Self
34    where
35        Q: Default,
36    {
37        Self::new(<Q>::default(), symbol)
38    }
39    /// create an instance of the [`Head`] from a given [`Tail`]
40    pub fn from_tail(
41        Tail {
42            next_state,
43            write_symbol,
44            ..
45        }: Tail<Q, A>,
46    ) -> Self {
47        Head {
48            state: next_state,
49            symbol: write_symbol,
50        }
51    }
52    /// Create a new instance from a 2-tuple: `(state, symbol)`
53    pub fn from_tuple((state, symbol): (State<Q>, A)) -> Self {
54        Self { state, symbol }
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) -> &A {
66        &self.symbol
67    }
68    /// returns a mutable reference to the current symbol
69    pub const fn symbol_mut(&mut self) -> &mut A {
70        &mut self.symbol
71    }
72    /// updates the current state
73    #[inline]
74    pub fn set_state(&mut self, state: Q) {
75        self.state_mut().set(state)
76    }
77    /// updates the current symbol
78    #[inline]
79    pub fn set_symbol(&mut self, symbol: A) {
80        self.symbol = symbol;
81    }
82    /// consumes the current instance to create another instance with the given state
83    #[inline]
84    pub fn with_state<Q2>(self, state: Q2) -> Head<Q2, A> {
85        Head {
86            state: State(state),
87            symbol: self.symbol,
88        }
89    }
90    /// consumes the current instance to create another instance with the given symbol
91    #[inline]
92    pub fn with_symbol<A2>(self, symbol: A2) -> Head<Q, A2> {
93        Head {
94            state: self.state,
95            symbol,
96        }
97    }
98    /// replaces the current values with the given state and symbol, returning the previous
99    /// instance of the [`Head`]
100    pub const fn replace(&mut self, state: State<Q>, symbol: A) -> Self {
101        Head {
102            state: self.replace_state(state),
103            symbol: self.replace_symbol(symbol),
104        }
105    }
106    /// [`replace`](core::mem::replace) the current state with the given state, returning the
107    /// previous state
108    pub const fn replace_state(&mut self, state: State<Q>) -> State<Q> {
109        core::mem::replace(self.state_mut(), state)
110    }
111    /// [`replace`](core::mem::replace) the current symbol with the given symbol, returning the
112    /// previous symbol
113    pub const fn replace_symbol(&mut self, symbol: A) -> A {
114        core::mem::replace(self.symbol_mut(), symbol)
115    }
116    /// [`swap`](core::mem::swap) the state and symbol of the current instance with another
117    pub const fn swap(&mut self, other: &mut Self) {
118        self.swap_state(other.state_mut());
119        self.swap_symbol(other.symbol_mut());
120    }
121    /// [`swap`](core::mem::swap) the current state with another
122    pub const fn swap_state(&mut self, other: &mut State<Q>) {
123        core::mem::swap(self.state_mut(), other)
124    }
125    /// [`swap`](core::mem::swap) the current symbol with another
126    pub const fn swap_symbol(&mut self, other: &mut A) {
127        core::mem::swap(self.symbol_mut(), other)
128    }
129    /// updates the current [State] and symbol
130    pub fn update(&mut self, state: Option<State<Q>>, symbol: Option<A>) {
131        if let Some(s) = state {
132            self.set_state(s.value())
133        }
134        if let Some(s) = symbol {
135            self.set_symbol(s)
136        }
137    }
138    /// returns a reference to the current state and symbol returing a 2-tuple
139    pub const fn as_tuple(&self) -> (&State<Q>, &A) {
140        (self.state(), self.symbol())
141    }
142    /// returns a mutable reference to the current state and symbol as a 2-tuple
143    pub const fn as_mut_tuple(&mut self) -> (&mut State<Q>, &mut A) {
144        (&mut self.state, &mut self.symbol)
145    }
146    /// Consumes the head and returns the current state and symbol as a 2-tuple
147    pub fn into_tuple(self) -> (State<Q>, A) {
148        (self.state, self.symbol)
149    }
150    /// associates the given tail with the current head, returning a new [`Rule`]
151    pub fn into_rule_with_tail(self, tail: Tail<Q, A>) -> Rule<Q, A>
152    where
153        Q: RawState,
154    {
155        Rule { head: self, tail }
156    }
157    /// tries reading the given tape using the head as its coordinates.
158    pub fn read_tape<T>(self, tape: &'_ [T]) -> Option<&A::Output>
159    where
160        A: core::slice::SliceIndex<[T]>,
161    {
162        tape.get(self.symbol)
163    }
164    /// returns a new head with immutable references to the current state and symbol
165    pub const fn view(&self) -> HeadRef<'_, Q, A> {
166        Head {
167            state: self.state().view(),
168            symbol: self.symbol(),
169        }
170    }
171    /// returns a new head with mutable references to the current state and symbol
172    pub const fn view_mut(&mut self) -> HeadMut<'_, Q, A> {
173        Head {
174            state: self.state.view_mut(),
175            symbol: &mut self.symbol,
176        }
177    }
178    /// use the given [`Tail`] to initialize a new [`HeadStep`] instance for performing a step
179    /// operation.
180    ///
181    /// **Note**: this method is _lazy_, meaning that the actual step is not performed until
182    /// an actionable method is called on the returned [`HeadStep`] instance.
183    pub fn step<'a, Q2, B>(&'a mut self, tail: Tail<Q2, B>) -> HeadStep<'a, Q, A, Q2, B>
184    where
185        Q2: RawState,
186    {
187        HeadStep { head: self, tail }
188    }
189}