use crate::{State, edge::Router};
use std::{collections::HashMap, sync::Arc};
#[derive(Clone, Debug)]
pub struct TriggerTable<S: State> {
pub outgoing: HashMap<String, Vec<CompiledEdge<S>>>,
pub incoming: HashMap<String, Vec<TriggerSource>>,
}
impl<S: State> Default for TriggerTable<S> {
fn default() -> Self {
Self {
outgoing: HashMap::new(),
incoming: HashMap::new(),
}
}
}
impl<S: State> TriggerTable<S> {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn add_outgoing(&mut self, from: String, edge: CompiledEdge<S>) {
self.outgoing.entry(from).or_default().push(edge);
}
pub fn add_incoming(&mut self, to: String, source: TriggerSource) {
self.incoming.entry(to).or_default().push(source);
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub fn sources(&self) -> impl Iterator<Item = &String> {
self.outgoing.keys()
}
pub fn targets(&self) -> impl Iterator<Item = &String> {
self.incoming.keys()
}
}
#[derive(Clone)]
pub enum CompiledEdge<S: State> {
Fixed {
target: String,
},
Conditional {
router: Arc<dyn Router<S>>,
path_map: super::PathMap,
},
}
impl<S: State> std::fmt::Debug for CompiledEdge<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Fixed { target } => f.debug_tuple("Fixed").field(target).finish(),
Self::Conditional { path_map, .. } => {
f.debug_tuple("Conditional").field(path_map).finish()
}
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum TriggerSource {
Edge {
from: String,
},
Send {
from: String,
},
}