1use crate::sender::{Recipient, Sender};
4use anyhow::{Result, anyhow as err};
5use std::sync::{Arc, Mutex};
6
7pub trait Notifier: Send + Sync {
9 fn notify(&self) -> Result<()>;
11
12 fn typeless(self) -> TypelessNotifier
13 where
14 Self: Sized + 'static,
15 {
16 TypelessNotifier {
17 notifier: Arc::new(self),
18 }
19 }
20}
21
22pub struct TypelessNotifier {
24 notifier: Arc<dyn Notifier>,
25}
26
27impl Notifier for TypelessNotifier {
28 fn notify(&self) -> Result<()> {
29 self.notifier.notify()
30 }
31}
32
33pub struct DropNotifier {
34 notifier: TypelessNotifier,
35}
36
37impl Drop for DropNotifier {
38 fn drop(&mut self) {
39 self.notifier.notify().ok();
40 }
41}
42
43pub struct TypedNotifier<M> {
44 message: M,
45 sender: Recipient<M>,
46}
47
48impl<M> TypedNotifier<M> {
49 pub fn new<S>(sender: S, message: M) -> Self
51 where
52 S: Sender<M> + 'static,
53 {
54 let sender = Recipient::new(sender);
55 Self { message, sender }
56 }
57
58 pub fn once(self) -> OnceNotifier<M> {
59 OnceNotifier {
60 notifier: Mutex::new(Some(self)),
61 }
62 }
63
64 pub fn notify_once(self) -> Result<()> {
65 self.sender.send(self.message)
66 }
67}
68
69impl<M> Notifier for TypedNotifier<M>
70where
71 M: Clone + Send + Sync + 'static,
72{
73 fn notify(&self) -> Result<()> {
74 self.sender.send(self.message.clone())
75 }
76}
77
78pub struct OnceNotifier<M> {
79 notifier: Mutex<Option<TypedNotifier<M>>>,
80}
81
82impl<M> OnceNotifier<M>
83where
84 M: Send + Sync + 'static,
85{
86 pub fn into_drop_notifier(self) -> DropNotifier {
87 DropNotifier {
88 notifier: self.typeless(),
89 }
90 }
91}
92
93impl<M> Notifier for OnceNotifier<M>
94where
95 M: Send + Sync + 'static,
96{
97 fn notify(&self) -> Result<()> {
98 self.notifier
99 .lock()
100 .map_err(|_| err!("Can't get access to a notifier"))?
101 .take()
102 .ok_or_else(|| err!("Notification has already sent"))?
103 .notify_once()
104 }
105}