eva-robots 0.1.7

Commons for EVA ICS v4
Documentation
use eva_common::prelude::*;
use serde::{Deserialize, Serialize};
use std::time::Duration;
use uuid::Uuid;

#[derive(Serialize, Deserialize)]
pub struct SequenceOwned {
    #[serde(alias = "uuid", deserialize_with = "crate::deserialize_uuid")]
    pub u: Uuid,
    pub seq: Vec<SequenceEntryOwned>,
    pub on_abort: Option<SequenceActionEntryOwned>,
    #[serde(
        deserialize_with = "eva_common::tools::deserialize_duration_from_micros",
        serialize_with = "eva_common::tools::serialize_duration_as_micros"
    )]
    pub timeout: Duration,
}

impl SequenceOwned {
    #[inline]
    pub fn new(timeout: Duration) -> Self {
        Self {
            u: Uuid::new_v4(),
            seq: <_>::default(),
            on_abort: <_>::default(),
            timeout,
        }
    }
    #[inline]
    pub fn uuid(&self) -> Uuid {
        self.u
    }
    #[inline]
    pub fn timeout(&self) -> Duration {
        self.timeout
    }
    #[inline]
    #[allow(clippy::cast_possible_truncation)]
    pub fn push_delay(&mut self, delay: Duration) {
        self.seq
            .push(SequenceEntryOwned::Delay(delay.as_micros() as u64));
    }
    #[inline]
    pub fn push_action(&mut self, action: SequenceActionOwned) {
        self.seq.push(SequenceEntryOwned::Actions(
            SequenceActionEntryOwned::Single(action),
        ));
    }
    #[inline]
    pub fn push_actions_multi(&mut self, actions: Vec<SequenceActionOwned>) {
        self.seq.push(SequenceEntryOwned::Actions(
            SequenceActionEntryOwned::Multi(actions),
        ));
    }
    pub fn max_expected_duration(&self) -> Duration {
        let mut duration: Duration = Duration::from_secs(0);
        for s in &self.seq {
            match s {
                SequenceEntryOwned::Delay(d) => duration += Duration::from_micros(*d),
                SequenceEntryOwned::Actions(a) => match a {
                    SequenceActionEntryOwned::Single(action) => duration += action.wait,
                    SequenceActionEntryOwned::Multi(actions) => {
                        duration += actions.iter().map(|a| a.wait).max().unwrap_or_default();
                    }
                },
            }
        }
        duration
    }
    #[inline]
    pub fn set_on_abort(&mut self, action: SequenceActionOwned) {
        self.on_abort = Some(SequenceActionEntryOwned::Single(action));
    }
    #[inline]
    pub fn set_on_abort_multi(&mut self, actions: Vec<SequenceActionOwned>) {
        self.on_abort = Some(SequenceActionEntryOwned::Multi(actions));
    }
    pub fn abort_timeout(&self) -> Duration {
        if let Some(ref on_abort) = self.on_abort {
            match on_abort {
                SequenceActionEntryOwned::Single(a) => a.wait,
                SequenceActionEntryOwned::Multi(actions) => {
                    actions.iter().map(|a| a.wait).max().unwrap_or_default()
                }
            }
        } else {
            Duration::from_secs(0)
        }
    }
}

#[derive(Serialize, Deserialize)]
#[serde(untagged)]
pub enum SequenceEntryOwned {
    Delay(u64),
    Actions(SequenceActionEntryOwned),
}

#[derive(Serialize, Deserialize)]
#[serde(untagged)]
pub enum SequenceActionEntryOwned {
    Single(SequenceActionOwned),
    Multi(Vec<SequenceActionOwned>),
}

#[derive(Serialize, Deserialize)]
pub struct SequenceActionOwned {
    #[serde(rename = "i")]
    pub oid: OID,
    pub params: Option<eva_common::actions::Params>,
    #[serde(
        deserialize_with = "eva_common::tools::deserialize_duration_from_micros",
        serialize_with = "eva_common::tools::serialize_duration_as_micros"
    )]
    pub wait: Duration,
}

impl SequenceActionOwned {
    pub fn new_unit(oid: OID, status: ItemStatus, value: Option<Value>, wait: Duration) -> Self {
        Self {
            oid,
            params: Some(eva_common::actions::Params::Unit(
                eva_common::actions::UnitParams {
                    status,
                    value: value.into(),
                },
            )),
            wait,
        }
    }
}