rstm_core/programs/impls/
imp_program_base.rs1use crate::programs::{ProgramBase, RawRuleset, Ruleset};
7use crate::rules::{Head, Instruction, Tail};
8use rstm_state::{IntoState, RawState, State};
9
10impl<R, I, Q, A> ProgramBase<R, Q, A, I>
11where
12 Q: RawState,
13 R: RawRuleset<Q, A, Rule = I>,
14 I: Instruction<Q, A>,
15{
16 pub const fn from_rules(rules: R) -> Self {
18 Self {
19 rules,
20 initial_state: None,
21 _marker: core::marker::PhantomData,
22 }
23 }
24 #[cfg(all(feature = "json", feature = "std"))]
25 pub fn load_from_json<P: AsRef<std::path::Path>>(path: P) -> crate::Result<Self>
27 where
28 Self: serde::de::DeserializeOwned,
29 {
30 let file = std::fs::File::open(path)?;
32 let reader = std::io::BufReader::new(file);
34 let p = serde_json::from_reader(reader)?;
36 Ok(p)
37 }
38 pub const fn rules(&self) -> &R {
40 &self.rules
41 }
42 #[allow(dead_code)]
43 pub(crate) const fn rules_mut(&mut self) -> &mut R {
45 &mut self.rules
46 }
47 pub fn initial_state(&self) -> Option<&State<Q>> {
49 self.initial_state.as_ref()
50 }
51 pub fn set_initial_state(&mut self, initial_state: Q) {
53 self.initial_state = Some(State(initial_state));
54 }
55 #[inline]
56 pub fn with_default_state<U>(self, initial_state: U) -> Self
58 where
59 U: IntoState<Q>,
60 {
61 Self {
62 initial_state: Some(initial_state.into_state()),
63 ..self
64 }
65 }
66 #[cfg(feature = "serde_json")]
67 pub fn to_json(&self) -> serde_json::Value
69 where
70 Self: serde::Serialize,
71 {
72 serde_json::to_value(self).expect("Failed to serialize the Program instance")
73 }
74 #[cfg(all(feature = "json", feature = "std"))]
75 pub fn export_json<P>(&self, path: P) -> std::io::Result<()>
80 where
81 P: AsRef<std::path::Path>,
82 Self: serde::Serialize,
83 {
84 let path = path.as_ref();
85 if path.extension().map(|os| os.to_str()).flatten() != Some("json") {
87 #[cfg(feature = "tracing")]
88 tracing::error!(
89 "the provided path does not end with `.json`; consider changing the file extension"
90 );
91 return Err(std::io::Error::new(
92 std::io::ErrorKind::InvalidInput,
93 "the provided path does not end with `.json`",
94 ));
95 }
96 let serialized = serde_json::to_string_pretty(self).unwrap();
97 std::fs::write(path, serialized)?;
98 #[cfg(feature = "tracing")]
99 tracing::info!("Program exported as JSON");
100 Ok(())
101 }
102
103 pub fn get_head(&self, head: &Head<Q, A>) -> Option<&Tail<Q, A>>
104 where
105 R: Ruleset<Q, A>,
106 R::Rule: Instruction<Q, A, Head = Head<Q, A>, Tail = Tail<Q, A>>,
107 {
108 self.rules().get(head)
109 }
110 pub fn find_tail(&self, state: State<&Q>, sym: &A) -> Option<&Tail<Q, A>>
113 where
114 R: Ruleset<Q, A>,
115 R::Rule: Instruction<Q, A, Head = Head<Q, A>, Tail = Tail<Q, A>>,
116 {
117 self.rules().find_tail(state, sym)
118 }
119 pub fn len(&self) -> usize
121 {
122 self.rules().len()
123 }
124 pub fn is_empty(&self) -> bool
127 {
128 self.rules().is_empty()
129 }
130}