eva_robots/
seq.rs

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}