rnotifylib/destination/
routed_destination.rs1use std::error::Error;
2use std::fmt::Debug;
3use serde::{Deserialize, Serialize};
4use crate::destination::MessageDestination;
5use crate::message::Message;
6use crate::message_router::RoutingInfo;
7
8pub trait RoutedDestination {
10 fn get_id(&self) -> &str;
13
14 fn get_destination(&self) -> &dyn MessageDestination;
17
18 fn get_routing_info(&self) -> &RoutingInfo;
20
21 fn send(&self, message: &Message) -> Result<(), Box<dyn Error>> {
22 self.get_destination().send(message)
23 }
24
25 fn is_root(&self) -> bool {
26 self.get_routing_info().get_routing_behaviour() == &MessageRoutingBehaviour::Root
27 }
28
29 fn get_routing_type(&self) -> &MessageRoutingBehaviour {
30 &self.get_routing_info().get_routing_behaviour()
31 }
32
33 fn should_receive(&self, m: &Message) -> bool {
34 self.get_routing_info().applies_to(m)
35 }
36}
37
38#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
40pub enum MessageRoutingBehaviour {
41 Root,
50 Drain,
53 Additive
55}
56
57impl MessageRoutingBehaviour {
58 pub fn always_send_messages(&self) -> bool {
59 match &self {
60 MessageRoutingBehaviour::Root => true,
61 MessageRoutingBehaviour::Additive => true,
62
63 MessageRoutingBehaviour::Drain => false,
64 }
65 }
66
67 pub fn always_receives_errors(&self) -> bool {
68 match &self {
69 MessageRoutingBehaviour::Root => true,
70 MessageRoutingBehaviour::Drain => false,
71 MessageRoutingBehaviour::Additive => false,
72 }
73 }
74}
75
76impl Default for MessageRoutingBehaviour {
77 fn default() -> Self {
78 MessageRoutingBehaviour::Additive
79 }
80}
81
82#[derive(Debug)]
85pub struct RoutedDestinationBase {
86 id: String,
87 destination: Box<dyn MessageDestination>,
89 routing_info: RoutingInfo,
90}
91
92impl RoutedDestinationBase {
93 pub fn new(id: String, destination: Box<dyn MessageDestination>, routing_info: RoutingInfo) -> Self {
94 Self {
95 id,
96 destination,
97 routing_info,
98 }
99 }
100
101 pub fn create<M: MessageDestination + 'static>(id: String, destination: M, routing_info: RoutingInfo) -> Self {
102 Self {
103 id,
104 destination: Box::new(destination),
105 routing_info,
106 }
107 }
108}
109
110impl RoutedDestination for RoutedDestinationBase {
111 fn get_id(&self) -> &str {
112 &self.id
113 }
114
115 fn get_destination(&self) -> &dyn MessageDestination {
116 &*self.destination
117 }
118
119 fn get_routing_info(&self) -> &RoutingInfo {
120 &self.routing_info
121 }
122}
123
124
125#[cfg(test)]
126mod test {
127 use std::sync::mpsc;
128 use std::sync::mpsc::TryRecvError;
129 use super::*;
130 use crate::destination::kinds::rust_receiver::RustReceiverDestination;
131 use crate::message::{Level, MessageDetail};
132 use crate::message::author::Author;
133
134 #[test]
135 pub fn test_send_message() {
136 let (send, recv) = mpsc::channel();
137 let dest = RoutedDestinationBase::create("test".to_owned(), RustReceiverDestination::create(send), RoutingInfo::root());
138
139 let message = Message::new(Level::Info,
140 None, MessageDetail::Raw("hello".to_owned()),
141 None, Author::parse("test".to_owned()), 104892);
142
143
144 assert_eq!(recv.try_recv(), Err(TryRecvError::Empty), "Should be empty before we send a message");
145
146 dest.send(&message).expect("Should not fail to send message");
147
148 assert_eq!(recv.try_recv(), Ok(message));
149 }
150}