use serde::{Deserialize, Serialize};
use super::model::*;
#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
pub enum Action {
Silent,
Labeled(LabeledAction),
}
const EMPTY_ARGUMENTS: [Value; 0] = [];
impl Action {
pub(crate) fn new(label: LabelIndex, arguments: Box<[Value]>) -> Self {
Action::Labeled(LabeledAction::new(label, arguments))
}
pub fn is_silent(&self) -> bool {
matches!(self, Action::Silent)
}
pub fn is_labeled(&self) -> bool {
matches!(self, Action::Labeled(_))
}
pub fn label_index(&self) -> Option<LabelIndex> {
match self {
Action::Silent => None,
Action::Labeled(labeled) => Some(labeled.label),
}
}
pub fn arguments(&self) -> &[Value] {
match self {
Action::Silent => &EMPTY_ARGUMENTS,
Action::Labeled(labeled) => labeled.arguments(),
}
}
}
#[derive(Serialize, Deserialize, Clone, Hash, Eq, PartialEq, Debug)]
pub struct LabeledAction {
pub(crate) label: LabelIndex,
pub(crate) arguments: Box<[Value]>,
}
impl LabeledAction {
pub(crate) fn new(label: LabelIndex, arguments: Box<[Value]>) -> Self {
LabeledAction { label, arguments }
}
pub fn new_with_network(network: &Network, label: &str, arguments: Box<[Value]>) -> Self {
LabeledAction {
label: network
.declarations
.action_labels
.get_index_of(label)
.unwrap(),
arguments,
}
}
pub fn label_index(&self) -> LabelIndex {
self.label
}
pub fn label<'n>(&self, network: &'n Network) -> Option<&'n String> {
network
.declarations
.action_labels
.get_index(self.label)
.map(|(action_name, _)| action_name)
}
pub fn arguments(&self) -> &[Value] {
&self.arguments
}
}
impl Into<Action> for LabeledAction {
fn into(self) -> Action {
Action::Labeled(self)
}
}