rstm_rules/program/
impl_program.rs

1/*
2    appellation: impl_rule_set <module>
3    authors: @FL03
4*/
5use crate::program::Program;
6use crate::{Rule, RuleVec};
7use rstm_core::{Head, Tail};
8use rstm_state::{RawState, State};
9
10use alloc::vec::{self, Vec};
11
12impl<Q, S> Program<Q, S>
13where
14    Q: RawState,
15{
16    /// returns a new, empty instance of the [`Program`]
17    pub const fn new() -> Self {
18        Self {
19            initial_state: None,
20            rules: RuleVec::new(),
21        }
22    }
23    /// returns a new instance of the [`Program`] using the given rules
24    pub fn from_rules<I>(iter: I) -> Self
25    where
26        I: IntoIterator<Item = Rule<Q, S>>,
27    {
28        Self {
29            initial_state: None,
30            rules: RuleVec::from_iter(iter),
31        }
32    }
33    /// Create a new instance of the [Program] using the given initial state.
34    pub fn from_state(initial_state: Q) -> Self {
35        Self {
36            initial_state: Some(State(initial_state)),
37            rules: RuleVec::new(),
38        }
39    }
40    /// Returns an owned reference to the initial state of the program.
41    pub fn initial_state(&self) -> Option<State<&'_ Q>> {
42        self.initial_state.as_ref().map(|state| state.view())
43    }
44    /// Returns a reference to the instructions.
45    pub const fn rules(&self) -> &RuleVec<Q, S> {
46        &self.rules
47    }
48    /// Returns a mutable reference to the instructions.
49    pub const fn rules_mut(&mut self) -> &mut RuleVec<Q, S> {
50        &mut self.rules
51    }
52    /// consumes the current instance to create another with the given default state
53    pub fn with_default_state(self, state: Q) -> Self {
54        Self {
55            initial_state: Some(State(state)),
56            ..self
57        }
58    }
59    /// consumes the current instance to create another with the given rules
60    pub fn with_rules<I>(self, rules: I) -> Self
61    where
62        I: IntoIterator<Item = Rule<Q, S>>,
63    {
64        Self {
65            rules: Vec::from_iter(rules),
66            ..self
67        }
68    }
69    /// Returns an iterator over the elements.
70    pub fn iter(&self) -> core::slice::Iter<'_, Rule<Q, S>> {
71        self.rules().iter()
72    }
73    /// Returns a mutable iterator over the elements.
74    pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, Rule<Q, S>> {
75        self.rules_mut().iter_mut()
76    }
77    /// returns an immutable reference to the tail for a given head; returns [`None`](Option::None)
78    /// if no match is found.
79    pub fn get(&self, head: &Head<Q, S>) -> Option<&Tail<Q, S>>
80    where
81        Q: PartialEq,
82        S: PartialEq,
83    {
84        self.iter().find_map(|i| {
85            if i.head() == head {
86                Some(i.tail())
87            } else {
88                None
89            }
90        })
91    }
92    /// returns a mutable reference to the tail for a given head; returns [`None`](Option::None)
93    /// if no match is found.
94    pub fn get_mut(&mut self, head: &Head<Q, S>) -> Option<&mut Tail<Q, S>>
95    where
96        Q: PartialEq,
97        S: PartialEq,
98    {
99        self.iter_mut().find_map(|i| {
100            if i.head() == head {
101                Some(i.tail_mut())
102            } else {
103                None
104            }
105        })
106    }
107    /// returns an immutable reference to the tail of a rule whose state and symbol match the
108    /// givens
109    pub fn find_tail(&self, state: State<&Q>, symbol: &S) -> Option<&Tail<Q, S>>
110    where
111        Q: PartialEq,
112        S: PartialEq,
113    {
114        self.iter().find_map(|i| {
115            if i.head().view() == (Head { state, symbol }) {
116                Some(i.tail())
117            } else {
118                None
119            }
120        })
121    }
122    /// returns a mutable reference to the tail for a given head; returns [`None`](Option::None)
123    /// if no match is found.
124    pub fn find_mut_tail(&mut self, head: Head<&Q, &S>) -> Option<&mut Tail<Q, S>>
125    where
126        Q: PartialEq,
127        S: PartialEq,
128    {
129        self.iter_mut().find_map(|i| {
130            if i.head().view() == head {
131                Some(i.tail_mut())
132            } else {
133                None
134            }
135        })
136    }
137    /// Returns a collection of rules whose head contains a match for the given state.
138    pub fn filter_by_state(&self, state: State<&Q>) -> Vec<&Rule<Q, S>>
139    where
140        Q: PartialEq,
141        S: PartialEq,
142    {
143        self.iter().filter(|i| *i.head() == state).collect()
144    }
145}
146
147impl<Q, S> AsRef<[Rule<Q, S>]> for Program<Q, S>
148where
149    Q: RawState,
150{
151    fn as_ref(&self) -> &[Rule<Q, S>] {
152        self.rules()
153    }
154}
155
156impl<Q, S> AsMut<[Rule<Q, S>]> for Program<Q, S>
157where
158    Q: RawState,
159{
160    fn as_mut(&mut self) -> &mut [Rule<Q, S>] {
161        self.rules_mut()
162    }
163}
164
165impl<Q, S> core::ops::Deref for Program<Q, S>
166where
167    Q: RawState,
168{
169    type Target = [Rule<Q, S>];
170
171    fn deref(&self) -> &Self::Target {
172        &self.rules
173    }
174}
175
176impl<Q, S> core::ops::DerefMut for Program<Q, S>
177where
178    Q: RawState,
179{
180    fn deref_mut(&mut self) -> &mut Self::Target {
181        &mut self.rules
182    }
183}
184
185impl<Q, S> core::ops::Index<Head<Q, S>> for Program<Q, S>
186where
187    Q: RawState + PartialEq,
188    S: PartialEq,
189{
190    type Output = Tail<Q, S>;
191
192    fn index(&self, index: Head<Q, S>) -> &Self::Output {
193        self.get(&index).unwrap()
194    }
195}
196
197impl<Q, S> From<Vec<Rule<Q, S>>> for Program<Q, S>
198where
199    Q: RawState + Default,
200{
201    fn from(rules: Vec<Rule<Q, S>>) -> Self {
202        Self {
203            initial_state: Some(State::default()),
204            rules,
205        }
206    }
207}
208
209impl<Q, S> Extend<Rule<Q, S>> for Program<Q, S>
210where
211    Q: RawState,
212{
213    fn extend<I: IntoIterator<Item = Rule<Q, S>>>(&mut self, iter: I) {
214        self.rules.extend(iter)
215    }
216}
217
218impl<Q, S> FromIterator<Rule<Q, S>> for Program<Q, S>
219where
220    Q: RawState + Default,
221{
222    fn from_iter<I: IntoIterator<Item = Rule<Q, S>>>(iter: I) -> Self {
223        let rules = RuleVec::from_iter(iter);
224        Self::from_rules(rules)
225    }
226}
227
228impl<Q, S> IntoIterator for Program<Q, S>
229where
230    Q: RawState,
231{
232    type Item = Rule<Q, S>;
233    type IntoIter = vec::IntoIter<Self::Item>;
234
235    fn into_iter(self) -> Self::IntoIter {
236        self.rules.into_iter()
237    }
238}