1use alloc::boxed::Box;
10use alloc::string::String;
11use alloc::vec::Vec;
12
13pub type Expr = String;
15
16#[derive(Clone, Copy, Debug, Default)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21pub struct Span {
22 pub line: u32,
24 pub column: u32,
26}
27
28impl Span {
29 pub const NONE: Span = Span { line: 0, column: 0 };
31
32 pub const fn new(line: u32, column: u32) -> Self {
34 Span { line, column }
35 }
36
37 pub const fn is_known(&self) -> bool {
39 self.line != 0
40 }
41}
42
43impl PartialEq for Span {
44 fn eq(&self, _other: &Self) -> bool {
45 true
46 }
47}
48impl Eq for Span {}
49impl core::hash::Hash for Span {
50 fn hash<H: core::hash::Hasher>(&self, _state: &mut H) {}
51}
52
53pub const VT_NS: &str = "https://w3id.org/vertep/vt#";
55pub const SCXML_NS: &str = "http://www.w3.org/2005/07/scxml";
57
58#[derive(Clone, Debug, PartialEq, Eq, Hash)]
61#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
62pub struct Extension {
63 pub ns: String,
65 pub local: String,
67 pub value: ExtensionValue,
69 pub position: u32,
72 pub span: Span,
74}
75
76#[derive(Clone, Debug, PartialEq, Eq, Hash)]
78#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
79pub enum ExtensionValue {
80 Attribute(String),
82 Element(String),
84}
85
86#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
88#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
89pub enum Binding {
90 #[default]
92 Early,
93 Late,
95}
96
97#[derive(Clone, Debug, PartialEq, Eq, Hash)]
100#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
101pub struct Chart {
102 pub name: Option<String>,
104 pub datamodel: String,
106 pub datamodel_explicit: bool,
108 pub binding: Binding,
110 pub binding_explicit: bool,
112 pub initial: Vec<String>,
114 pub data: Vec<Data>,
116 pub script: Option<Script>,
118 pub states: Vec<State>,
120 pub extensions: Vec<Extension>,
122 pub span: Span,
124}
125
126impl Default for Chart {
127 fn default() -> Self {
128 Chart {
129 name: None,
130 datamodel: String::from("null"),
131 datamodel_explicit: false,
132 binding: Binding::Early,
133 binding_explicit: false,
134 initial: Vec::new(),
135 data: Vec::new(),
136 script: None,
137 states: Vec::new(),
138 extensions: Vec::new(),
139 span: Span::NONE,
140 }
141 }
142}
143
144#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
146#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
147pub enum HistoryType {
148 #[default]
150 Shallow,
151 Deep,
153}
154
155#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
157#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
158pub enum StateElement {
159 State,
161 Parallel,
163 Final,
165 History(HistoryType),
167}
168
169#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
172#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
173pub enum StateKind {
174 Atomic,
176 Compound,
178 Parallel,
180 Final,
182 History(HistoryType),
184}
185
186#[derive(Clone, Debug, PartialEq, Eq, Hash)]
188#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
189pub struct State {
190 pub id: String,
192 pub id_generated: bool,
194 pub element: StateElement,
196 pub initial: Vec<String>,
198 pub initial_element: Option<Initial>,
200 pub children: Vec<State>,
202 pub transitions: Vec<Transition>,
204 pub onentry: Vec<Block>,
206 pub onexit: Vec<Block>,
208 pub data: Vec<Data>,
210 pub invokes: Vec<Invoke>,
212 pub donedata: Option<DoneData>,
214 pub extensions: Vec<Extension>,
216 pub span: Span,
218}
219
220impl State {
221 pub fn new(id: impl Into<String>, element: StateElement) -> Self {
223 State {
224 id: id.into(),
225 id_generated: false,
226 element,
227 initial: Vec::new(),
228 initial_element: None,
229 children: Vec::new(),
230 transitions: Vec::new(),
231 onentry: Vec::new(),
232 onexit: Vec::new(),
233 data: Vec::new(),
234 invokes: Vec::new(),
235 donedata: None,
236 extensions: Vec::new(),
237 span: Span::NONE,
238 }
239 }
240
241 pub fn kind(&self) -> StateKind {
243 match self.element {
244 StateElement::State if self.children.is_empty() => StateKind::Atomic,
245 StateElement::State => StateKind::Compound,
246 StateElement::Parallel => StateKind::Parallel,
247 StateElement::Final => StateKind::Final,
248 StateElement::History(h) => StateKind::History(h),
249 }
250 }
251}
252
253#[derive(Clone, Debug, PartialEq, Eq, Hash)]
255#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
256pub struct Initial {
257 pub transition: Transition,
259 pub extensions: Vec<Extension>,
261 pub span: Span,
263}
264
265#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
267#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
268pub enum TransitionType {
269 #[default]
271 External,
272 Internal,
274}
275
276#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
279#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
280pub struct Transition {
281 pub events: Vec<String>,
283 pub cond: Option<Expr>,
285 pub targets: Vec<String>,
287 pub kind: TransitionType,
289 pub kind_explicit: bool,
291 pub body: Block,
293 pub extensions: Vec<Extension>,
295 pub span: Span,
297}
298
299pub type Block = Vec<Exec>;
301
302#[derive(Clone, Debug, PartialEq, Eq, Hash)]
305#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
306pub struct Exec {
307 pub kind: ExecKind,
309 pub extensions: Vec<Extension>,
311 pub span: Span,
313}
314
315impl Exec {
316 pub fn new(kind: ExecKind) -> Self {
318 Exec {
319 kind,
320 extensions: Vec::new(),
321 span: Span::NONE,
322 }
323 }
324}
325
326#[derive(Clone, Debug, PartialEq, Eq, Hash)]
328#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
329pub enum ExecKind {
330 Raise {
332 event: String,
334 },
335 Send(Box<Send>),
337 Cancel {
339 sendid: Option<String>,
341 sendidexpr: Option<Expr>,
343 },
344 Log {
346 label: Option<String>,
348 expr: Option<Expr>,
350 },
351 Assign {
353 location: Expr,
355 expr: Option<Expr>,
357 content: Option<String>,
359 },
360 Script(Script),
362 If {
365 branches: Vec<IfBranch>,
367 },
368 Foreach {
370 array: Expr,
372 item: String,
374 index: Option<String>,
376 body: Block,
378 },
379 Extension(Extension),
381}
382
383#[derive(Clone, Debug, PartialEq, Eq, Hash)]
385#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
386pub struct IfBranch {
387 pub cond: Option<Expr>,
389 pub body: Block,
391 pub span: Span,
393}
394
395#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
397#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
398pub struct Send {
399 pub event: Option<String>,
401 pub eventexpr: Option<Expr>,
403 pub target: Option<String>,
405 pub targetexpr: Option<Expr>,
407 pub type_: Option<String>,
409 pub typeexpr: Option<Expr>,
411 pub id: Option<String>,
413 pub idlocation: Option<Expr>,
415 pub delay: Option<String>,
417 pub delayexpr: Option<Expr>,
419 pub namelist: Vec<String>,
421 pub params: Vec<Param>,
423 pub content: Option<Content>,
425}
426
427#[derive(Clone, Debug, PartialEq, Eq, Hash)]
429#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
430pub struct Param {
431 pub name: String,
433 pub expr: Option<Expr>,
435 pub location: Option<Expr>,
437 pub span: Span,
439}
440
441#[derive(Clone, Debug, PartialEq, Eq, Hash)]
443#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
444pub struct Content {
445 pub expr: Option<Expr>,
447 pub body: Option<String>,
449 pub span: Span,
451}
452
453#[derive(Clone, Debug, PartialEq, Eq, Hash)]
455#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
456pub struct Script {
457 pub src: Option<String>,
459 pub body: Option<String>,
461 pub span: Span,
463}
464
465#[derive(Clone, Debug, PartialEq, Eq, Hash)]
468#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
469pub struct Data {
470 pub id: String,
472 pub src: Option<String>,
474 pub expr: Option<Expr>,
476 pub content: Option<String>,
478 pub extensions: Vec<Extension>,
480 pub span: Span,
482}
483
484#[derive(Clone, Debug, PartialEq, Eq, Hash)]
486#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
487pub struct DoneData {
488 pub content: Option<Content>,
490 pub params: Vec<Param>,
492 pub span: Span,
494}
495
496#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
499#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
500pub struct Invoke {
501 pub type_: Option<String>,
503 pub typeexpr: Option<Expr>,
505 pub src: Option<String>,
507 pub srcexpr: Option<Expr>,
509 pub id: Option<String>,
511 pub idlocation: Option<Expr>,
513 pub namelist: Vec<String>,
515 pub autoforward: bool,
517 pub params: Vec<Param>,
519 pub content: Option<Content>,
521 pub finalize: Block,
523 pub extensions: Vec<Extension>,
525 pub span: Span,
527}