1use crate::local_only::LocalOnly;
7use mesh::MeshPayload;
8use std::fmt::Debug;
9use std::sync::Arc;
10
11#[derive(Clone, Debug, MeshPayload)]
21pub struct Interrupt {
22 inner: InterruptInner,
23}
24
25impl Default for Interrupt {
26 fn default() -> Self {
27 Self::null()
28 }
29}
30
31impl Interrupt {
32 pub fn null() -> Self {
34 Self::from_event(pal_event::Event::new())
36 }
37
38 pub fn from_event(event: pal_event::Event) -> Self {
42 Self {
43 inner: InterruptInner::Event(Arc::new(event)),
44 }
45 }
46
47 pub fn from_cell(cell: mesh::Cell<pal_event::Event>) -> Self {
52 Self {
53 inner: InterruptInner::Cell(Arc::new(cell)),
54 }
55 }
56
57 pub fn from_fn<F>(f: F) -> Self
62 where
63 F: 'static + Send + Sync + Fn(),
64 {
65 Self {
66 inner: InterruptInner::Fn(LocalOnly(Arc::new(f))),
67 }
68 }
69
70 pub fn deliver(&self) {
72 match &self.inner {
73 InterruptInner::Event(event) => event.signal(),
74 InterruptInner::Cell(cell) => cell.with(|event| event.signal()),
75 InterruptInner::Fn(LocalOnly(f)) => f(),
76 }
77 }
78
79 pub fn event(&self) -> Option<&pal_event::Event> {
81 match &self.inner {
82 InterruptInner::Event(event) => Some(event.as_ref()),
83 _ => None,
84 }
85 }
86}
87
88#[derive(Clone, MeshPayload)]
89enum InterruptInner {
90 Event(Arc<pal_event::Event>),
91 Cell(Arc<mesh::Cell<pal_event::Event>>),
92 Fn(LocalOnly<Arc<dyn Send + Sync + Fn()>>),
93}
94
95impl Debug for InterruptInner {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 match self {
98 InterruptInner::Event(_) => f.pad("Event"),
99 InterruptInner::Cell(_) => f.pad("Cell"),
100 InterruptInner::Fn(_) => f.pad("Fn"),
101 }
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::Interrupt;
108 use pal_async::async_test;
109
110 #[test]
111 fn test_interrupt_event() {
112 let event = pal_event::Event::new();
113 let interrupt = Interrupt::from_event(event.clone());
114 interrupt.deliver();
115 assert!(event.try_wait());
116 }
117
118 #[async_test]
119 async fn test_interrupt_cell() {
120 let mut event = pal_event::Event::new();
121 let (mut updater, cell) = mesh::cell(event.clone());
122 let interrupt = Interrupt::from_cell(cell);
123 interrupt.deliver();
124 assert!(event.try_wait());
125 event = pal_event::Event::new();
126 interrupt.deliver();
127 assert!(!event.try_wait());
128 updater.set(event.clone()).await;
129 interrupt.deliver();
130 assert!(event.try_wait());
131 }
132}