use std::any::TypeId;
use std::sync::Arc;
use std::time::Duration;
use dex_protocol::dex::Value as ProtoValue;
use crate::SubFlowOptions;
pub struct Wait {
pub(crate) kind: WaitKind,
}
pub(crate) enum WaitKind {
SkipImmediately,
AllOf(Vec<Condition>),
AnyOf(Vec<Condition>),
AnyCombinationOf(Vec<ConditionCombination>),
}
impl Wait {
pub fn skip_immediately() -> Self {
Self {
kind: WaitKind::SkipImmediately,
}
}
pub fn until(condition: Condition) -> Self {
Self::all_of([condition])
}
pub fn all_of(conditions: impl IntoIterator<Item = Condition>) -> Self {
Self {
kind: WaitKind::AllOf(conditions.into_iter().collect()),
}
}
pub fn any_of(conditions: impl IntoIterator<Item = Condition>) -> Self {
Self {
kind: WaitKind::AnyOf(conditions.into_iter().collect()),
}
}
pub fn any_combination_of(
combinations: impl IntoIterator<Item = ConditionCombination>,
) -> Self {
Self {
kind: WaitKind::AnyCombinationOf(combinations.into_iter().collect()),
}
}
}
#[derive(Clone)]
pub struct Condition {
pub(crate) identity: Arc<ConditionIdentity>,
pub(crate) id: Option<String>,
pub(crate) kind: ConditionKind,
}
pub(crate) struct ConditionIdentity;
#[derive(Clone)]
pub(crate) enum ConditionKind {
Timer(Duration),
Channel {
name: String,
instance: Option<String>,
at_least: Option<usize>,
at_most: Option<usize>,
},
SubFlow(Box<SubFlowDefinition>),
}
#[derive(Clone)]
pub(crate) struct SubFlowDefinition {
pub(crate) flow_type: &'static str,
pub(crate) type_id: TypeId,
pub(crate) input: ProtoValue,
pub(crate) options: SubFlowOptions,
}
impl Condition {
pub(crate) fn timer(duration: Duration) -> Self {
Self {
identity: Arc::new(ConditionIdentity),
id: None,
kind: ConditionKind::Timer(duration),
}
}
pub(crate) fn channel(
name: String,
instance: Option<String>,
at_least: Option<usize>,
at_most: Option<usize>,
) -> Self {
Self {
identity: Arc::new(ConditionIdentity),
id: None,
kind: ConditionKind::Channel {
name,
instance,
at_least,
at_most,
},
}
}
pub(crate) fn sub_flow(definition: SubFlowDefinition) -> Self {
let id = definition.options.condition_id.clone();
Self {
identity: Arc::new(ConditionIdentity),
id,
kind: ConditionKind::SubFlow(Box::new(definition)),
}
}
pub fn with_id(mut self, id: impl Into<String>) -> Self {
self.id = Some(id.into());
self
}
}
pub struct ConditionCombination {
pub(crate) conditions: Vec<Condition>,
}
impl ConditionCombination {
pub fn all_of(conditions: impl IntoIterator<Item = Condition>) -> Self {
Self {
conditions: conditions.into_iter().collect(),
}
}
}