use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec::Vec;
pub type Expr = String;
#[derive(Clone, Copy, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Span {
pub line: u32,
pub column: u32,
}
impl Span {
pub const NONE: Span = Span { line: 0, column: 0 };
pub const fn new(line: u32, column: u32) -> Self {
Span { line, column }
}
pub const fn is_known(&self) -> bool {
self.line != 0
}
}
impl PartialEq for Span {
fn eq(&self, _other: &Self) -> bool {
true
}
}
impl Eq for Span {}
impl core::hash::Hash for Span {
fn hash<H: core::hash::Hasher>(&self, _state: &mut H) {}
}
pub const VT_NS: &str = "https://w3id.org/vertep/vt#";
pub const SCXML_NS: &str = "http://www.w3.org/2005/07/scxml";
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Extension {
pub ns: String,
pub local: String,
pub value: ExtensionValue,
pub position: u32,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ExtensionValue {
Attribute(String),
Element(String),
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Binding {
#[default]
Early,
Late,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Chart {
pub name: Option<String>,
pub datamodel: String,
pub datamodel_explicit: bool,
pub binding: Binding,
pub binding_explicit: bool,
pub initial: Vec<String>,
pub data: Vec<Data>,
pub script: Option<Script>,
pub states: Vec<State>,
pub extensions: Vec<Extension>,
pub span: Span,
}
impl Default for Chart {
fn default() -> Self {
Chart {
name: None,
datamodel: String::from("null"),
datamodel_explicit: false,
binding: Binding::Early,
binding_explicit: false,
initial: Vec::new(),
data: Vec::new(),
script: None,
states: Vec::new(),
extensions: Vec::new(),
span: Span::NONE,
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum HistoryType {
#[default]
Shallow,
Deep,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum StateElement {
State,
Parallel,
Final,
History(HistoryType),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum StateKind {
Atomic,
Compound,
Parallel,
Final,
History(HistoryType),
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct State {
pub id: String,
pub id_generated: bool,
pub element: StateElement,
pub initial: Vec<String>,
pub initial_element: Option<Initial>,
pub children: Vec<State>,
pub transitions: Vec<Transition>,
pub onentry: Vec<Block>,
pub onexit: Vec<Block>,
pub data: Vec<Data>,
pub invokes: Vec<Invoke>,
pub donedata: Option<DoneData>,
pub extensions: Vec<Extension>,
pub span: Span,
}
impl State {
pub fn new(id: impl Into<String>, element: StateElement) -> Self {
State {
id: id.into(),
id_generated: false,
element,
initial: Vec::new(),
initial_element: None,
children: Vec::new(),
transitions: Vec::new(),
onentry: Vec::new(),
onexit: Vec::new(),
data: Vec::new(),
invokes: Vec::new(),
donedata: None,
extensions: Vec::new(),
span: Span::NONE,
}
}
pub fn kind(&self) -> StateKind {
match self.element {
StateElement::State if self.children.is_empty() => StateKind::Atomic,
StateElement::State => StateKind::Compound,
StateElement::Parallel => StateKind::Parallel,
StateElement::Final => StateKind::Final,
StateElement::History(h) => StateKind::History(h),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Initial {
pub transition: Transition,
pub extensions: Vec<Extension>,
pub span: Span,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum TransitionType {
#[default]
External,
Internal,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Transition {
pub events: Vec<String>,
pub cond: Option<Expr>,
pub targets: Vec<String>,
pub kind: TransitionType,
pub kind_explicit: bool,
pub body: Block,
pub extensions: Vec<Extension>,
pub span: Span,
}
pub type Block = Vec<Exec>;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Exec {
pub kind: ExecKind,
pub extensions: Vec<Extension>,
pub span: Span,
}
impl Exec {
pub fn new(kind: ExecKind) -> Self {
Exec {
kind,
extensions: Vec::new(),
span: Span::NONE,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ExecKind {
Raise {
event: String,
},
Send(Box<Send>),
Cancel {
sendid: Option<String>,
sendidexpr: Option<Expr>,
},
Log {
label: Option<String>,
expr: Option<Expr>,
},
Assign {
location: Expr,
expr: Option<Expr>,
content: Option<String>,
},
Script(Script),
If {
branches: Vec<IfBranch>,
},
Foreach {
array: Expr,
item: String,
index: Option<String>,
body: Block,
},
Extension(Extension),
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct IfBranch {
pub cond: Option<Expr>,
pub body: Block,
pub span: Span,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Send {
pub event: Option<String>,
pub eventexpr: Option<Expr>,
pub target: Option<String>,
pub targetexpr: Option<Expr>,
pub type_: Option<String>,
pub typeexpr: Option<Expr>,
pub id: Option<String>,
pub idlocation: Option<Expr>,
pub delay: Option<String>,
pub delayexpr: Option<Expr>,
pub namelist: Vec<String>,
pub params: Vec<Param>,
pub content: Option<Content>,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Param {
pub name: String,
pub expr: Option<Expr>,
pub location: Option<Expr>,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Content {
pub expr: Option<Expr>,
pub body: Option<String>,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Script {
pub src: Option<String>,
pub body: Option<String>,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Data {
pub id: String,
pub src: Option<String>,
pub expr: Option<Expr>,
pub content: Option<String>,
pub extensions: Vec<Extension>,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct DoneData {
pub content: Option<Content>,
pub params: Vec<Param>,
pub span: Span,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Invoke {
pub type_: Option<String>,
pub typeexpr: Option<Expr>,
pub src: Option<String>,
pub srcexpr: Option<Expr>,
pub id: Option<String>,
pub idlocation: Option<Expr>,
pub namelist: Vec<String>,
pub autoforward: bool,
pub params: Vec<Param>,
pub content: Option<Content>,
pub finalize: Block,
pub extensions: Vec<Extension>,
pub span: Span,
}