1use eva_common::prelude::*;
2use serde::Serialize;
3use std::time::Duration;
4use uuid::Uuid;
5
6#[derive(Serialize)]
7pub struct Sequence<'a> {
8 pub u: Uuid,
9 pub seq: Vec<SequenceEntry<'a>>,
10 pub on_abort: Option<SequenceActionEntry<'a>>,
11 #[serde(serialize_with = "eva_common::tools::serialize_duration_as_micros")]
12 pub timeout: Duration,
13}
14
15impl<'a> Sequence<'a> {
16 #[inline]
17 pub fn new(timeout: Duration) -> Self {
18 Self {
19 u: Uuid::new_v4(),
20 seq: <_>::default(),
21 on_abort: <_>::default(),
22 timeout,
23 }
24 }
25 #[inline]
26 pub fn uuid(&self) -> Uuid {
27 self.u
28 }
29 #[inline]
30 pub fn timeout(&self) -> Duration {
31 self.timeout
32 }
33 #[inline]
34 #[allow(clippy::cast_possible_truncation)]
35 pub fn push_delay(&mut self, delay: Duration) {
36 self.seq
37 .push(SequenceEntry::Delay(delay.as_micros() as u64));
38 }
39 #[inline]
40 pub fn push_action(&mut self, action: SequenceAction<'a>) {
41 self.seq
42 .push(SequenceEntry::Actions(SequenceActionEntry::Single(action)));
43 }
44 #[inline]
45 pub fn push_actions_multi(&mut self, actions: Vec<SequenceAction<'a>>) {
46 self.seq
47 .push(SequenceEntry::Actions(SequenceActionEntry::Multi(actions)));
48 }
49 pub fn max_expected_duration(&self) -> Duration {
50 let mut duration: Duration = Duration::from_secs(0);
51 for s in &self.seq {
52 match s {
53 SequenceEntry::Delay(d) => duration += Duration::from_micros(*d),
54 SequenceEntry::Actions(a) => match a {
55 SequenceActionEntry::Single(action) => duration += action.wait,
56 SequenceActionEntry::Multi(actions) => {
57 duration += actions.iter().map(|a| a.wait).max().unwrap_or_default();
58 }
59 },
60 }
61 }
62 duration
63 }
64 #[inline]
65 pub fn set_on_abort(&mut self, action: SequenceAction<'a>) {
66 self.on_abort = Some(SequenceActionEntry::Single(action));
67 }
68 #[inline]
69 pub fn set_on_abort_multi(&mut self, actions: Vec<SequenceAction<'a>>) {
70 self.on_abort = Some(SequenceActionEntry::Multi(actions));
71 }
72 pub fn abort_timeout(&self) -> Duration {
73 if let Some(ref on_abort) = self.on_abort {
74 match on_abort {
75 SequenceActionEntry::Single(a) => a.wait,
76 SequenceActionEntry::Multi(actions) => {
77 actions.iter().map(|a| a.wait).max().unwrap_or_default()
78 }
79 }
80 } else {
81 Duration::from_secs(0)
82 }
83 }
84}
85
86#[derive(Serialize)]
87#[serde(untagged)]
88pub enum SequenceEntry<'a> {
89 Delay(u64),
90 Actions(SequenceActionEntry<'a>),
91}
92
93#[derive(Serialize)]
94#[serde(untagged)]
95pub enum SequenceActionEntry<'a> {
96 Single(SequenceAction<'a>),
97 Multi(Vec<SequenceAction<'a>>),
98}
99
100#[derive(Serialize)]
101pub struct SequenceAction<'a> {
102 #[serde(rename = "i")]
103 pub oid: &'a OID,
104 pub params: Option<eva_common::actions::Params>,
105 #[serde(serialize_with = "eva_common::tools::serialize_duration_as_micros")]
106 pub wait: Duration,
107}
108
109impl<'a> SequenceAction<'a> {
110 pub fn new_unit(oid: &'a OID, value: Value, wait: Duration) -> Self {
111 Self {
112 oid,
113 params: Some(eva_common::actions::Params::Unit(
114 eva_common::actions::UnitParams { value },
115 )),
116 wait,
117 }
118 }
119}