1#![cfg(any(feature = "tokio", feature = "async-io"))]
2
3#[cfg(all(not(doc), feature = "tokio", feature = "async-io"))]
4compile_error!("`tokio` and `async-io` are mutually exclusive; only one may be enabled");
5
6use std::{io, os::fd::AsRawFd, task::Poll};
7
8use crate::{EventReader, event::InputEvent, reader::Report, util::r#async::AsyncHelper};
9
10#[derive(Debug)]
18pub struct AsyncReports<'a> {
19 helper: AsyncHelper,
20 reader: &'a mut EventReader,
21}
22
23impl<'a> AsyncReports<'a> {
24 pub(crate) fn new(reader: &'a mut EventReader) -> io::Result<Self> {
25 Ok(Self {
26 helper: AsyncHelper::new(reader.as_raw_fd())?,
27 reader,
28 })
29 }
30
31 pub async fn next_report(&mut self) -> io::Result<Report> {
35 self.helper
36 .asyncify(|| match self.reader.reports().next() {
37 Some(res) => Poll::Ready(res),
38 None => Poll::Pending,
39 })
40 .await
41 }
42}
43
44#[derive(Debug)]
52pub struct AsyncEvents<'a> {
53 helper: AsyncHelper,
54 reader: &'a mut EventReader,
55}
56
57impl<'a> AsyncEvents<'a> {
58 pub(crate) fn new(reader: &'a mut EventReader) -> io::Result<Self> {
59 Ok(Self {
60 helper: AsyncHelper::new(reader.as_raw_fd())?,
61 reader,
62 })
63 }
64
65 pub async fn next_event(&mut self) -> io::Result<InputEvent> {
69 self.helper
70 .asyncify(|| match self.reader.events().next() {
71 Some(res) => Poll::Ready(res),
72 None => Poll::Pending,
73 })
74 .await
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use std::io;
81
82 use crate::{
83 event::{Rel, RelEvent, Syn},
84 test::{check_events, pair},
85 util::r#async::test::AsyncTest,
86 };
87
88 #[test]
89 fn smoke() -> io::Result<()> {
90 let (uinput, evdev) = pair(|b| b.with_rel_axes([Rel::DIAL]))?;
91 let mut reader = evdev.into_reader()?;
92
93 {
94 let event = AsyncTest::new(async { reader.async_events()?.next_event().await }, || {
95 uinput.write(&[RelEvent::new(Rel::DIAL, 1).into()])
96 })
97 .run()?;
98
99 check_events([event], [RelEvent::new(Rel::DIAL, 1).into()]);
100 }
101
102 let ev = reader.events().next().unwrap()?;
103 check_events([ev], [Syn::REPORT.into()]);
104
105 let report = AsyncTest::new(
106 async { reader.async_reports()?.next_report().await },
107 || uinput.write(&[RelEvent::new(Rel::DIAL, 2).into()]),
108 )
109 .run()?;
110
111 assert_eq!(report.len(), 2);
112 check_events(
113 report,
114 [RelEvent::new(Rel::DIAL, 2).into(), Syn::REPORT.into()],
115 );
116
117 Ok(())
118 }
119}