1use core::{
2 pin::Pin,
3 task::{Context, Poll},
4};
5use futures::Stream;
6
7pub trait Interrupt {
8 type Error;
9
10 fn enable(&mut self) -> Result<(), Self::Error>;
11
12 fn disable(&mut self) -> Result<(), Self::Error>;
13
14 fn poll_interrupt(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>>;
15
16 fn poll_interrupt_unpin(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>>
17 where
18 Self: Unpin,
19 {
20 Pin::new(self).poll_interrupt(cx)
21 }
22
23 fn interrupts(&mut self) -> Interrupts<Self>
26 where
27 Self: Unpin,
28 {
29 Interrupts {
30 interrupt: self,
31 is_enabled: false,
32 }
33 }
34}
35
36pub struct Interrupts<'a, T: Interrupt + ?Sized> {
37 interrupt: &'a mut T,
38 is_enabled: bool,
39}
40
41impl<T> Stream for Interrupts<'_, T>
42where
43 T: Interrupt + Unpin + ?Sized,
44{
45 type Item = Result<(), T::Error>;
46
47 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
48 if !self.is_enabled {
49 self.interrupt.enable()?;
50 self.is_enabled = true;
51 }
52
53 self.interrupt.poll_interrupt_unpin(cx).map(Some)
54 }
55}
56
57impl<T> Drop for Interrupts<'_, T>
58where
59 T: Interrupt + ?Sized,
60{
61 fn drop(&mut self) {
62 self.interrupt.disable().ok();
63 }
64}