rstm_programs/
rule_map.rs

1/*
2    Appellation: rule_map <module>
3    Created At: 2025.09.04:22:20:45
4    Contrib: @FL03
5*/
6
7mod impl_rule_map;
8
9use core::hash::Hash;
10use rstm_core::{Head, Rule, Tail};
11use rstm_state::RawState;
12use std::collections::hash_map;
13
14use crate::HeadMap;
15
16#[derive(Clone, Debug, Default)]
17#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
18pub struct RuleMap<Q, S>
19where
20    Q: RawState + Eq + Hash,
21    S: Eq + Hash,
22{
23    pub(crate) rules: HeadMap<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            rules: HeadMap::new(),
34        }
35    }
36    /// returns a new instance of the [`RuleMap`] composed from an iterator of rules
37    pub fn from_rules<I>(iter: I) -> Self
38    where
39        I: IntoIterator<Item = Rule<Q, S>>,
40    {
41        Self::from_iter(iter.into_iter().map(|Rule { head, tail }| (head, tail)))
42    }
43    /// consumes the current instance to create another with the given instructions
44    pub fn with_instructions(
45        self,
46        instructions: impl IntoIterator<Item = (Head<Q, S>, Tail<Q, S>)>,
47    ) -> Self {
48        Self {
49            rules: HeadMap::from_iter(instructions),
50        }
51    }
52    /// returns an immutable reference to the set of rules.
53    pub const fn rules(&self) -> &HeadMap<Q, S> {
54        &self.rules
55    }
56    /// returns a mutable reference to the set of rules.
57    pub const fn rules_mut(&mut self) -> &mut HeadMap<Q, S> {
58        &mut self.rules
59    }
60    /// Clears the set of rules.
61    pub fn clear(&mut self) {
62        self.rules_mut().clear();
63    }
64    /// returns an the entry for the given head within the set of rules.
65    pub fn rule(&mut self, head: Head<Q, S>) -> hash_map::Entry<'_, Head<Q, S>, Tail<Q, S>> {
66        self.rules_mut().entry(head)
67    }
68    /// returns an immutable reference to the tail of the rule for the given head; returns none
69    /// if the head is not found.
70    pub fn get<K>(&self, head: &K) -> Option<&Tail<Q, S>>
71    where
72        K: Eq + Hash,
73        Head<Q, S>: core::borrow::Borrow<K>,
74    {
75        self.rules().get(head)
76    }
77    /// returns a mutable reference to the tail of the rule for the given head; returns none if
78    /// the head is not found.
79    pub fn get_mut<K>(&mut self, head: &K) -> Option<&mut Tail<Q, S>>
80    where
81        K: Eq + Hash,
82        Head<Q, S>: core::borrow::Borrow<K>,
83    {
84        self.rules_mut().get_mut(head)
85    }
86    /// returns the tail of the rule for the given head; returns none if the head is not found
87    /// within the set of rules.
88    pub fn get_tail_view<K>(&self, head: &K) -> Option<Tail<&Q, &S>>
89    where
90        K: Eq + Hash,
91        Head<Q, S>: core::borrow::Borrow<K>,
92    {
93        self.get(head).map(|tail| tail.view())
94    }
95    /// insert a new rule into the set of rules.
96    pub fn insert(&mut self, head: Head<Q, S>, tail: Tail<Q, S>)
97    where
98        Q: RawState + Eq + Hash,
99        S: Eq + Hash,
100    {
101        self.rules_mut().insert(head, tail);
102    }
103    /// insert a new rule into the set of rules.
104    pub fn insert_rule(&mut self, rule: Rule<Q, S>)
105    where
106        Q: RawState + Eq + Hash,
107        S: Eq + Hash,
108    {
109        self.insert(rule.head, rule.tail);
110    }
111    /// returns true if the set of rules is empty.
112    pub fn is_empty(&self) -> bool {
113        self.rules().is_empty()
114    }
115    /// returns the number of rules in the set.
116    pub fn len(&self) -> usize {
117        self.rules().len()
118    }
119    /// returns a mutable reference to the tail of the rule for the given head; inserts the
120    /// tail if the head is not found.
121    pub fn or_insert(&mut self, head: Head<Q, S>, tail: Tail<Q, S>) -> &mut Tail<Q, S> {
122        self.rule(head).or_insert(tail)
123    }
124    /// returns a mutable reference to the tail of the rule for the given head; inserts the
125    /// tail if the head is not found.
126    pub fn or_insert_with<F>(&mut self, head: Head<Q, S>, f: F) -> &mut Tail<Q, S>
127    where
128        F: FnOnce() -> Tail<Q, S>,
129    {
130        self.rule(head).or_insert_with(f)
131    }
132    /// returns a mutable reference to the tail of the rule for the given head; inserts the
133    /// default tail if the head is not found.
134    pub fn or_insert_default(&mut self, head: Head<Q, S>) -> &mut Tail<Q, S>
135    where
136        Q: Default,
137        S: Default,
138    {
139        self.or_insert(head, Tail::default())
140    }
141    /// Removes a rule from the set of rules.
142    pub fn remove(&mut self, head: &Head<Q, S>) -> Option<Tail<Q, S>> {
143        self.rules_mut().remove(head)
144    }
145}
146
147#[allow(deprecated)]
148impl<Q, S> RuleMap<Q, S>
149where
150    Q: RawState + Eq + Hash,
151    S: Eq + Hash,
152{
153    #[deprecated(since = "0.1.0", note = "use `get` instead, which is more concise.")]
154    pub fn get_head<K>(&self, head: &K) -> Option<&Tail<Q, S>>
155    where
156        K: Eq + Hash,
157        Head<Q, S>: core::borrow::Borrow<K>,
158    {
159        self.rules().get(head)
160    }
161}