1mod impl_rule_map;
7
8use super::Rule;
9
10use core::hash::Hash;
11use rstm_core::{Head, Tail};
12use rstm_state::{RawState, State};
13use std::collections::hash_map::{self, HashMap};
14
15#[derive(Clone, Debug, Default)]
16#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
17pub struct RuleMap<Q, S>
18where
19 Q: RawState + Eq + Hash,
20 S: Eq + Hash,
21{
22 pub(crate) initial_state: Option<State<Q>>,
23 pub(crate) rules: HashMap<Head<Q, S>, Tail<Q, S>>,
24}
25
26impl<Q, S> RuleMap<Q, S>
27where
28 Q: RawState + Eq + Hash,
29 S: Eq + Hash,
30{
31 pub fn new() -> Self {
32 Self {
33 initial_state: None,
34 rules: HashMap::new(),
35 }
36 }
37 pub fn from_state(initial_state: State<Q>) -> Self {
39 Self {
40 initial_state: Some(initial_state),
41 rules: HashMap::new(),
42 }
43 }
44 #[allow(clippy::should_implement_trait)]
45 pub fn from_iter<I>(iter: I) -> Self
47 where
48 I: IntoIterator<Item = (Head<Q, S>, Tail<Q, S>)>,
49 {
50 Self {
51 initial_state: None,
52 rules: HashMap::from_iter(iter),
53 }
54 }
55
56 pub fn from_rules<I>(iter: I) -> Self
57 where
58 I: IntoIterator<Item = super::Rule<Q, S>>,
59 {
60 Self::from_iter(iter.into_iter().map(|Rule { head, tail }| (head, tail)))
61 }
62 pub fn with_initial_state(self, state: State<Q>) -> Self {
64 Self {
65 initial_state: Some(state),
66 ..self
67 }
68 }
69 pub fn with_instructions(
71 self,
72 instructions: impl IntoIterator<Item = (Head<Q, S>, Tail<Q, S>)>,
73 ) -> Self {
74 Self {
75 rules: HashMap::from_iter(instructions),
76 ..self
77 }
78 }
79 pub fn initial_state(&self) -> Option<State<&'_ Q>> {
81 self.initial_state.as_ref().map(|state| state.view())
82 }
83 pub const fn rules(&self) -> &HashMap<Head<Q, S>, Tail<Q, S>> {
85 &self.rules
86 }
87 pub const fn rules_mut(&mut self) -> &mut HashMap<Head<Q, S>, Tail<Q, S>> {
89 &mut self.rules
90 }
91 pub fn clear(&mut self) {
93 self.rules_mut().clear();
94 }
95 pub fn rule(&mut self, head: Head<Q, S>) -> hash_map::Entry<'_, Head<Q, S>, Tail<Q, S>> {
97 self.rules_mut().entry(head)
98 }
99 pub fn get<K>(&self, head: &K) -> Option<&Tail<Q, S>>
102 where
103 K: Eq + Hash,
104 Head<Q, S>: core::borrow::Borrow<K>,
105 {
106 self.rules().get(head)
107 }
108 pub fn get_mut<K>(&mut self, head: &K) -> Option<&mut Tail<Q, S>>
111 where
112 K: Eq + Hash,
113 Head<Q, S>: core::borrow::Borrow<K>,
114 {
115 self.rules_mut().get_mut(head)
116 }
117 pub fn get_tail_view<K>(&self, head: &K) -> Option<Tail<&Q, &S>>
120 where
121 K: Eq + Hash,
122 Head<Q, S>: core::borrow::Borrow<K>,
123 {
124 self.get(head).map(|tail| tail.view())
125 }
126 pub fn insert(&mut self, head: Head<Q, S>, tail: Tail<Q, S>)
128 where
129 Q: RawState + Eq + Hash,
130 S: Eq + Hash,
131 {
132 self.rules_mut().insert(head, tail);
133 }
134 pub fn insert_rule(&mut self, rule: Rule<Q, S>)
136 where
137 Q: RawState + Eq + Hash,
138 S: Eq + Hash,
139 {
140 self.insert(rule.head, rule.tail);
141 }
142 pub fn is_empty(&self) -> bool {
144 self.rules().is_empty()
145 }
146 pub fn len(&self) -> usize {
148 self.rules().len()
149 }
150 pub fn or_insert(&mut self, head: Head<Q, S>, tail: Tail<Q, S>) -> &mut Tail<Q, S> {
153 self.rule(head).or_insert(tail)
154 }
155 pub fn or_insert_with<F>(&mut self, head: Head<Q, S>, f: F) -> &mut Tail<Q, S>
158 where
159 F: FnOnce() -> Tail<Q, S>,
160 {
161 self.rule(head).or_insert_with(f)
162 }
163 pub fn or_insert_default(&mut self, head: Head<Q, S>) -> &mut Tail<Q, S>
166 where
167 Q: Default,
168 S: Default,
169 {
170 self.or_insert(head, Tail::default())
171 }
172 pub fn remove(&mut self, head: &Head<Q, S>) -> Option<Tail<Q, S>> {
174 self.rules_mut().remove(head)
175 }
176}
177
178#[allow(deprecated)]
179impl<Q, S> RuleMap<Q, S>
180where
181 Q: RawState + Eq + Hash,
182 S: Eq + Hash,
183{
184 #[deprecated(since = "0.1.0", note = "use `get` instead, which is more concise.")]
185 pub fn get_head<K>(&self, head: &K) -> Option<&Tail<Q, S>>
186 where
187 K: Eq + Hash,
188 Head<Q, S>: core::borrow::Borrow<K>,
189 {
190 self.rules().get(head)
191 }
192}