1use std::{
2 fmt::{self, Display},
3 hash::Hash,
4};
5
6use elfo_macros::msg_raw as msg;
7
8use crate::{self as elfo, envelope::Envelope};
9
10pub use self::map::MapRouter;
11
12mod map;
13
14pub trait Router<C>: Send + Sync + 'static {
15 type Key: Clone + Hash + Eq + Display + Send + Sync; fn update(&self, _config: &C) {}
18 fn route(&self, envelope: &Envelope) -> Outcome<Self::Key>;
19}
20
21#[derive(Debug)]
23#[non_exhaustive]
24pub enum Outcome<T> {
25 Unicast(T),
29 GentleUnicast(T),
33 Multicast(Vec<T>),
37 GentleMulticast(Vec<T>),
41 Broadcast,
43 Discard,
46 Default,
48}
49
50assert_eq_size!(Outcome<u64>, [u8; 32]);
51assert_eq_size!(Outcome<u128>, [u8; 32]);
52
53impl<T> Outcome<T> {
54 #[inline]
56 pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Outcome<U> {
57 match self {
58 Outcome::Unicast(val) => Outcome::Unicast(f(val)),
59 Outcome::GentleUnicast(val) => Outcome::GentleUnicast(f(val)),
60 Outcome::Multicast(list) => Outcome::Multicast(list.into_iter().map(f).collect()),
61 Outcome::GentleMulticast(list) => {
62 Outcome::GentleMulticast(list.into_iter().map(f).collect())
63 }
64 Outcome::Broadcast => Outcome::Broadcast,
65 Outcome::Discard => Outcome::Discard,
66 Outcome::Default => Outcome::Default,
67 }
68 }
69
70 #[inline]
72 pub fn or(self, outcome: Outcome<T>) -> Self {
73 match self {
74 Outcome::Default => outcome,
75 _ => self,
76 }
77 }
78}
79
80impl<C> Router<C> for () {
81 type Key = Singleton;
82
83 #[inline]
84 fn route(&self, envelope: &Envelope) -> Outcome<Self::Key> {
85 use crate::messages::*;
86
87 msg!(match envelope {
88 ValidateConfig | Terminate | Ping => Outcome::GentleUnicast(Singleton),
91 _ => Outcome::Unicast(Singleton),
92 })
93 }
94}
95
96#[derive(Debug, Clone, Hash, PartialEq, Eq)]
98pub struct Singleton;
99
100impl fmt::Display for Singleton {
101 #[inline]
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 f.write_str("_")
105 }
106}