1use crate::program::Program;
7
8use crate::types::RuleVec;
9use rstm_core::{Head, Rule, Tail};
10use rstm_state::{RawState, State};
11
12use alloc::vec::{self, Vec};
13
14impl<Q, A> Program<Q, A>
15where
16 Q: RawState,
17{
18 pub fn get(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>>
21 where
22 Q: PartialEq,
23 A: PartialEq,
24 {
25 self.iter().find_map(|i| {
26 if i.head() == head {
27 Some(i.tail())
28 } else {
29 None
30 }
31 })
32 }
33 pub fn get_mut(&mut self, head: &Head<Q, A>) -> Option<&mut Tail<Q, A>>
36 where
37 Q: PartialEq,
38 A: PartialEq,
39 {
40 self.iter_mut().find_map(|i| {
41 if i.head() == head {
42 Some(i.tail_mut())
43 } else {
44 None
45 }
46 })
47 }
48 pub fn find_tail(&self, state: State<&Q>, symbol: &A) -> Option<&Tail<Q, A>>
51 where
52 Q: PartialEq,
53 A: PartialEq,
54 {
55 self.iter().find_map(|i| {
56 if i.head().view() == (Head { state, symbol }) {
57 Some(i.tail())
58 } else {
59 None
60 }
61 })
62 }
63 pub fn find_mut_tail(&mut self, state: State<&Q>, symbol: &A) -> Option<&mut Tail<Q, A>>
66 where
67 Q: PartialEq,
68 A: PartialEq,
69 {
70 self.iter_mut().find_map(|i| {
71 if i.head().view() == (Head { state, symbol }) {
72 Some(i.tail_mut())
73 } else {
74 None
75 }
76 })
77 }
78 pub fn filter_by_state(&self, state: State<&Q>) -> Vec<&Rule<Q, A>>
80 where
81 Q: PartialEq,
82 {
83 self.iter().filter(|i| *i.head() == state).collect()
84 }
85 #[cfg(all(feature = "json", feature = "std"))]
86 pub fn export_json<P: AsRef<std::path::Path>>(&self, path: P) -> std::io::Result<()>
88 where
89 Q: serde::Serialize,
90 A: serde::Serialize,
91 {
92 let serialized = serde_json::to_string_pretty(self).unwrap();
93 std::fs::write(path, serialized)?;
94 #[cfg(feature = "tracing")]
95 tracing::info!("Program exported as JSON");
96 Ok(())
97 }
98}
99
100impl<Q, A> AsRef<[Rule<Q, A>]> for Program<Q, A>
101where
102 Q: RawState,
103{
104 fn as_ref(&self) -> &[Rule<Q, A>] {
105 self.rules()
106 }
107}
108
109impl<Q, A> AsMut<[Rule<Q, A>]> for Program<Q, A>
110where
111 Q: RawState,
112{
113 fn as_mut(&mut self) -> &mut [Rule<Q, A>] {
114 self.rules_mut()
115 }
116}
117
118impl<Q, A> core::ops::Deref for Program<Q, A>
119where
120 Q: RawState,
121{
122 type Target = [Rule<Q, A>];
123
124 fn deref(&self) -> &Self::Target {
125 &self.rules
126 }
127}
128
129impl<Q, A> core::ops::DerefMut for Program<Q, A>
130where
131 Q: RawState,
132{
133 fn deref_mut(&mut self) -> &mut Self::Target {
134 &mut self.rules
135 }
136}
137
138impl<Q, A> core::ops::Index<Head<Q, A>> for Program<Q, A>
139where
140 Q: RawState + PartialEq,
141 A: PartialEq,
142{
143 type Output = Tail<Q, A>;
144
145 fn index(&self, index: Head<Q, A>) -> &Self::Output {
146 self.get(&index).unwrap()
147 }
148}
149
150impl<Q, A> From<Vec<Rule<Q, A>>> for Program<Q, A>
151where
152 Q: RawState + Default,
153{
154 fn from(rules: Vec<Rule<Q, A>>) -> Self {
155 Self::from_rules(rules)
156 }
157}
158
159impl<Q, A> Extend<Rule<Q, A>> for Program<Q, A>
160where
161 Q: RawState,
162{
163 fn extend<I: IntoIterator<Item = Rule<Q, A>>>(&mut self, iter: I) {
164 self.rules_mut().extend(iter)
165 }
166}
167
168impl<Q, A> Extend<(Head<Q, A>, Tail<Q, A>)> for Program<Q, A>
169where
170 Q: RawState,
171{
172 fn extend<I: IntoIterator<Item = (Head<Q, A>, Tail<Q, A>)>>(&mut self, iter: I) {
173 self.rules_mut()
174 .extend(iter.into_iter().map(|(head, tail)| Rule { head, tail }))
175 }
176}
177
178impl<Q, A> FromIterator<Rule<Q, A>> for Program<Q, A>
179where
180 Q: RawState,
181{
182 fn from_iter<I: IntoIterator<Item = Rule<Q, A>>>(iter: I) -> Self {
183 Self {
184 initial_state: None,
185 rules: iter.into_iter().collect::<RuleVec<Q, A>>(),
186 }
187 }
188}
189
190impl<Q, A> FromIterator<(Head<Q, A>, Tail<Q, A>)> for Program<Q, A>
191where
192 Q: RawState,
193{
194 fn from_iter<I: IntoIterator<Item = (Head<Q, A>, Tail<Q, A>)>>(iter: I) -> Self {
195 Self::from_rules(iter.into_iter().map(|(head, tail)| Rule { head, tail }))
196 }
197}
198
199impl<Q, A> IntoIterator for Program<Q, A>
200where
201 Q: RawState,
202{
203 type Item = Rule<Q, A>;
204 type IntoIter = vec::IntoIter<Self::Item>;
205
206 fn into_iter(self) -> Self::IntoIter {
207 self.rules.into_iter()
208 }
209}