momba_explore/explore/
actions.rs

1use serde::{Deserialize, Serialize};
2
3use super::model::*;
4
5/// An *action* which is either [*silent*][Action::Silent] or [*labeled*][Action::Labeled].
6///
7/// An action is either the *silent action* or a *labeled action* instantiated with
8/// a sequence of values coined *arguments*.
9/// While action labels are generally represented as strings, we internally store
10/// the index into the [action label declarations][Declarations] of the [Network].
11/// Hence, the [label index][Action::label_index] is only meaningful with respect to
12/// a particular instance of [Network].
13/// The string action label can be retrieved via [LabeledAction::label] providing
14/// the network the action belongs to.
15#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
16pub enum Action {
17    /// The silent action.
18    Silent,
19    /// A labeled action.
20    Labeled(LabeledAction),
21}
22
23const EMPTY_ARGUMENTS: [Value; 0] = [];
24
25impl Action {
26    /// Creates a new labeled action.
27    pub(crate) fn new(label: LabelIndex, arguments: Box<[Value]>) -> Self {
28        Action::Labeled(LabeledAction::new(label, arguments))
29    }
30
31    /// Returns `true` if the action is silent.
32    pub fn is_silent(&self) -> bool {
33        matches!(self, Action::Silent)
34    }
35
36    /// Returns `true` if the action is labeled.
37    pub fn is_labeled(&self) -> bool {
38        matches!(self, Action::Labeled(_))
39    }
40
41    /// Returns the index of the action's label or [None][None] if the action is silent.
42    pub fn label_index(&self) -> Option<LabelIndex> {
43        match self {
44            Action::Silent => None,
45            Action::Labeled(labeled) => Some(labeled.label),
46        }
47    }
48
49    /// Returns a slice representing the arguments of the action.
50    ///
51    /// For the silent action the slice is empty.
52    pub fn arguments(&self) -> &[Value] {
53        match self {
54            Action::Silent => &EMPTY_ARGUMENTS,
55            Action::Labeled(labeled) => labeled.arguments(),
56        }
57    }
58}
59
60/// Label and arguments associated with a [labeled action](Action::Labeled).
61#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
62pub struct LabeledAction {
63    /// The label of the action.
64    pub(crate) label: LabelIndex,
65    /// The arguments of the action.
66    pub(crate) arguments: Box<[Value]>,
67}
68
69impl LabeledAction {
70    /// Crates a new labeled action.
71    pub(crate) fn new(label: LabelIndex, arguments: Box<[Value]>) -> Self {
72        LabeledAction { label, arguments }
73    }
74
75    pub fn new_with_network(network: &Network, label: &str, arguments: Box<[Value]>) -> Self {
76        LabeledAction {
77            label: network
78                .declarations
79                .action_labels
80                .get_index_of(label)
81                .unwrap(),
82            arguments,
83        }
84    }
85
86    /// Returns the index of the action's label.
87    pub fn label_index(&self) -> LabelIndex {
88        self.label
89    }
90
91    /// Retrieves the name of the action's label from the network.
92    pub fn label<'n>(&self, network: &'n Network) -> Option<&'n String> {
93        network
94            .declarations
95            .action_labels
96            .get_index(self.label)
97            .map(|(action_name, _)| action_name)
98    }
99
100    /// Returns a slice representing the arguments of the action.
101    pub fn arguments(&self) -> &[Value] {
102        &self.arguments
103    }
104}
105
106impl Into<Action> for LabeledAction {
107    fn into(self) -> Action {
108        Action::Labeled(self)
109    }
110}