1#![allow(deprecated)]
7#![cfg(feature = "alloc")]
8use crate::{Head, Rule, RuleVec, Tail};
9use alloc::vec::{self, Vec};
10use rstm_state::{RawState, State};
11
12#[deprecated(since = "0.1.4", note = "Use the `Program` implementation instead")]
13#[derive(Clone, Debug, Default)]
18#[cfg_attr(
19 feature = "serde",
20 derive(serde::Deserialize, serde::Serialize),
21 serde(deny_unknown_fields, rename_all = "snake_case")
22)]
23#[repr(C)]
24pub struct InstructionSet<Q = String, A = char>
25where
26 Q: RawState,
27{
28 pub(crate) initial_state: State<Q>,
29 pub(crate) rules: Vec<Rule<Q, A>>,
30}
31
32impl<Q, A> InstructionSet<Q, A>
33where
34 Q: RawState,
35{
36 pub const fn new(initial_state: Q) -> Self {
38 Self {
39 initial_state: State(initial_state),
40 rules: Vec::new(),
41 }
42 }
43 pub fn from_rules<I>(iter: I) -> Self
45 where
46 Q: Default,
47 I: IntoIterator<Item = Rule<Q, A>>,
48 {
49 Self {
50 initial_state: State::default(),
51 rules: Vec::from_iter(iter),
52 }
53 }
54 pub fn from_state(initial_state: Q) -> Self {
56 Self {
57 initial_state: State(initial_state),
58 rules: Vec::new(),
59 }
60 }
61 #[cfg(all(feature = "json", feature = "std"))]
62 pub fn load_from_json<P: AsRef<std::path::Path>>(path: P) -> crate::Result<Self>
64 where
65 InstructionSet<Q, A>: serde::de::DeserializeOwned,
66 {
67 let file = std::fs::File::open(path)?;
69 let reader = std::io::BufReader::new(file);
71 let p = serde_json::from_reader(reader)?;
73 Ok(p)
74 }
75 pub fn initial_state(&self) -> State<&Q> {
77 self.initial_state.view()
78 }
79 pub const fn rules(&self) -> &RuleVec<Q, A> {
81 &self.rules
82 }
83 pub const fn rules_mut(&mut self) -> &mut RuleVec<Q, A> {
85 &mut self.rules
86 }
87 pub fn with_default_state(self, state: Q) -> Self {
89 Self {
90 initial_state: State(state),
91 ..self
92 }
93 }
94 pub fn with_rules<I>(self, rules: I) -> Self
96 where
97 I: IntoIterator<Item = Rule<Q, A>>,
98 {
99 Self {
100 rules: Vec::from_iter(rules),
101 ..self
102 }
103 }
104 pub fn iter(&self) -> core::slice::Iter<'_, Rule<Q, A>> {
106 self.rules().iter()
107 }
108 pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, Rule<Q, A>> {
110 self.rules_mut().iter_mut()
111 }
112 pub fn get<K>(&self, head: &K) -> Option<&Tail<Q, A>>
115 where
116 Q: PartialEq,
117 A: PartialEq,
118 K: core::borrow::Borrow<Head<Q, A>>,
119 {
120 self.iter().find_map(|i| {
121 if i.head() == head.borrow() {
122 Some(i.tail())
123 } else {
124 None
125 }
126 })
127 }
128 pub fn get_mut<K>(&mut self, head: &K) -> Option<&mut Tail<Q, A>>
131 where
132 Q: PartialEq,
133 A: PartialEq,
134 K: core::borrow::Borrow<Head<Q, A>>,
135 {
136 self.iter_mut().find_map(|i| {
137 if i.head() == head.borrow() {
138 Some(i.tail_mut())
139 } else {
140 None
141 }
142 })
143 }
144 pub fn find_tail(&self, state: State<&Q>, symbol: &A) -> Option<&Tail<Q, A>>
147 where
148 Q: PartialEq,
149 A: PartialEq,
150 {
151 self.iter().find_map(|i| {
152 if i.head().view() == (Head { state, symbol }) {
153 Some(i.tail())
154 } else {
155 None
156 }
157 })
158 }
159 pub fn find_mut_tail(&mut self, state: State<&Q>, symbol: &A) -> Option<&mut Tail<Q, A>>
162 where
163 Q: PartialEq,
164 A: PartialEq,
165 {
166 self.iter_mut().find_map(|i| {
167 if i.head().view() == (Head { state, symbol }) {
168 Some(i.tail_mut())
169 } else {
170 None
171 }
172 })
173 }
174 pub fn filter_by_state(&self, state: State<&Q>) -> Vec<&Rule<Q, A>>
176 where
177 Q: PartialEq,
178 {
179 self.iter().filter(|i| *i.head() == state).collect()
180 }
181 #[cfg(all(feature = "json", feature = "std"))]
182 pub fn export_json<P>(&self, path: P) -> std::io::Result<()>
187 where
188 P: AsRef<std::path::Path>,
189 Q: serde::Serialize,
190 A: serde::Serialize,
191 {
192 let path = path.as_ref();
193 if path.extension().map(|os| os.to_str()).flatten() != Some("json") {
195 #[cfg(feature = "tracing")]
196 tracing::error!(
197 "the provided path does not end with `.json`; consider changing the file extension"
198 );
199 return Err(std::io::Error::new(
200 std::io::ErrorKind::InvalidInput,
201 "the provided path does not end with `.json`",
202 ));
203 }
204 let serialized = serde_json::to_string_pretty(self).unwrap();
205 std::fs::write(path, serialized)?;
206 #[cfg(feature = "tracing")]
207 tracing::info!("Program exported as JSON");
208 Ok(())
209 }
210}
211
212impl<Q, A> InstructionSet<Q, A>
213where
214 Q: RawState,
215{
216 #[cfg(feature = "serde_json")]
217 pub fn to_json(&self) -> serde_json::Value
219 where
220 A: serde::Serialize,
221 Q: serde::Serialize,
222 {
223 serde_json::to_value(self).expect("Failed to serialize the Program instance")
224 }
225}
226
227impl<Q, A> AsRef<[Rule<Q, A>]> for InstructionSet<Q, A>
228where
229 Q: RawState,
230{
231 fn as_ref(&self) -> &[Rule<Q, A>] {
232 &self.rules
233 }
234}
235
236impl<Q, A> AsMut<[Rule<Q, A>]> for InstructionSet<Q, A>
237where
238 Q: RawState,
239{
240 fn as_mut(&mut self) -> &mut [Rule<Q, A>] {
241 &mut self.rules
242 }
243}
244
245impl<Q, A> core::ops::Deref for InstructionSet<Q, A>
246where
247 Q: RawState,
248{
249 type Target = [Rule<Q, A>];
250
251 fn deref(&self) -> &Self::Target {
252 &self.rules
253 }
254}
255
256impl<Q, A> core::ops::DerefMut for InstructionSet<Q, A>
257where
258 Q: RawState,
259{
260 fn deref_mut(&mut self) -> &mut Self::Target {
261 &mut self.rules
262 }
263}
264
265impl<Q, A> core::ops::Index<Head<Q, A>> for InstructionSet<Q, A>
266where
267 Q: RawState + PartialEq,
268 A: PartialEq,
269{
270 type Output = Tail<Q, A>;
271
272 fn index(&self, index: Head<Q, A>) -> &Self::Output {
273 self.get(&index).unwrap()
274 }
275}
276
277impl<Q, A> From<Vec<Rule<Q, A>>> for InstructionSet<Q, A>
278where
279 Q: RawState + Default,
280{
281 fn from(rules: Vec<Rule<Q, A>>) -> Self {
282 Self::from_rules(rules)
283 }
284}
285
286impl<Q, A> Extend<Rule<Q, A>> for InstructionSet<Q, A>
287where
288 Q: RawState,
289{
290 fn extend<I: IntoIterator<Item = Rule<Q, A>>>(&mut self, iter: I) {
291 self.rules_mut().extend(iter)
292 }
293}
294
295impl<Q, A> Extend<(Head<Q, A>, Tail<Q, A>)> for InstructionSet<Q, A>
296where
297 Q: RawState,
298{
299 fn extend<I: IntoIterator<Item = (Head<Q, A>, Tail<Q, A>)>>(&mut self, iter: I) {
300 self.rules_mut()
301 .extend(iter.into_iter().map(|(head, tail)| Rule { head, tail }))
302 }
303}
304
305impl<Q, A> FromIterator<Rule<Q, A>> for InstructionSet<Q, A>
306where
307 Q: RawState + Default,
308{
309 fn from_iter<I: IntoIterator<Item = Rule<Q, A>>>(iter: I) -> Self {
310 Self {
311 initial_state: State::default(),
312 rules: iter.into_iter().collect::<RuleVec<Q, A>>(),
313 }
314 }
315}
316
317impl<Q, A> FromIterator<(Head<Q, A>, Tail<Q, A>)> for InstructionSet<Q, A>
318where
319 Q: RawState + Default,
320{
321 fn from_iter<I: IntoIterator<Item = (Head<Q, A>, Tail<Q, A>)>>(iter: I) -> Self {
322 Self::from_rules(iter.into_iter().map(|(head, tail)| Rule { head, tail }))
323 }
324}
325
326impl<Q, A> IntoIterator for InstructionSet<Q, A>
327where
328 Q: RawState,
329{
330 type Item = Rule<Q, A>;
331 type IntoIter = vec::IntoIter<Self::Item>;
332
333 fn into_iter(self) -> Self::IntoIter {
334 self.rules.into_iter()
335 }
336}