Skip to main content

wowlab_types/types/sim/rotation/
mod.rs

1//! Authored rotation syntax shared by parsing, validation, and runtime construction.
2
3mod action;
4mod condition;
5
6use serde::{Deserialize, Serialize};
7
8use super::FastMap;
9
10#[rustfmt::skip]
11pub use action::{Action, Hand, TargetIf, TargetIfMode, VarOp};
12#[rustfmt::skip]
13pub use condition::{ArithOp, CompareOp, Condition, FieldRead, MinMaxOp, UnaryMathOp};
14
15/// Current authored rotation wire-format version.
16pub const ROTATION_FORMAT_VERSION: u32 = 1;
17
18/// Parsed rotation.
19#[derive(Clone, Debug, Deserialize, Serialize)]
20#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
21#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
22#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
23pub struct Rotation {
24    pub version: u32,
25    pub name: String,
26    #[cfg_attr(feature = "wasm", tsify(type = "Record<string, Condition>"))]
27    pub variables: FastMap<String, Condition>,
28    pub actions: Vec<Action>,
29    #[cfg_attr(feature = "wasm", tsify(type = "Record<string, Action[]>"))]
30    pub lists: FastMap<String, Vec<Action>>,
31}
32
33impl Rotation {
34    /// An empty, no-op rotation.
35    #[must_use]
36    pub fn empty() -> Self {
37        Self {
38            version: ROTATION_FORMAT_VERSION,
39            name: String::new(),
40            variables: FastMap::default(),
41            actions: Vec::new(),
42            lists: FastMap::default(),
43        }
44    }
45
46    /// Whether this is the explicit internal no-op rotation.
47    #[must_use]
48    pub fn is_empty(&self) -> bool {
49        self.version == ROTATION_FORMAT_VERSION
50            && self.name.is_empty()
51            && self.variables.is_empty()
52            && self.actions.is_empty()
53            && self.lists.is_empty()
54    }
55}
56
57#[cfg(test)]
58mod tests;