Add raw_stream::enumerate() -> Iterator<RawDevice>
This commit is contained in:
parent
be24cc15be
commit
9f63c9a0eb
3 changed files with 42 additions and 18 deletions
18
src/lib.rs
18
src/lib.rs
|
@ -86,7 +86,6 @@ pub mod uinput;
|
|||
#[cfg(feature = "tokio")]
|
||||
mod tokio_stream;
|
||||
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use std::{fmt, io};
|
||||
|
||||
|
@ -241,28 +240,17 @@ impl fmt::Debug for InputEvent {
|
|||
/// an empty iterator or omits the devices that could not be opened.
|
||||
pub fn enumerate() -> EnumerateDevices {
|
||||
EnumerateDevices {
|
||||
readdir: std::fs::read_dir("/dev/input").ok(),
|
||||
inner: raw_stream::enumerate(),
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EnumerateDevices {
|
||||
readdir: Option<std::fs::ReadDir>,
|
||||
inner: raw_stream::EnumerateDevices,
|
||||
}
|
||||
impl Iterator for EnumerateDevices {
|
||||
type Item = Device;
|
||||
fn next(&mut self) -> Option<Device> {
|
||||
let readdir = self.readdir.as_mut()?;
|
||||
loop {
|
||||
if let Ok(entry) = readdir.next()? {
|
||||
let path = entry.path();
|
||||
let fname = path.file_name().unwrap();
|
||||
if fname.as_bytes().starts_with(b"event") {
|
||||
if let Ok(dev) = Device::open(&path) {
|
||||
return Some(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.inner.next().map(Device::from_raw_device)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -518,6 +518,38 @@ fn vec_spare_capacity_mut<T>(v: &mut Vec<T>) -> &mut [mem::MaybeUninit<T>] {
|
|||
}
|
||||
}
|
||||
|
||||
/// Crawls `/dev/input` for evdev devices.
|
||||
///
|
||||
/// Will not bubble up any errors in opening devices or traversing the directory. Instead returns
|
||||
/// an empty iterator or omits the devices that could not be opened.
|
||||
pub fn enumerate() -> EnumerateDevices {
|
||||
EnumerateDevices {
|
||||
readdir: std::fs::read_dir("/dev/input").ok(),
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EnumerateDevices {
|
||||
readdir: Option<std::fs::ReadDir>,
|
||||
}
|
||||
impl Iterator for EnumerateDevices {
|
||||
type Item = RawDevice;
|
||||
fn next(&mut self) -> Option<RawDevice> {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
let readdir = self.readdir.as_mut()?;
|
||||
loop {
|
||||
if let Ok(entry) = readdir.next()? {
|
||||
let path = entry.path();
|
||||
let fname = path.file_name().unwrap();
|
||||
if fname.as_bytes().starts_with(b"event") {
|
||||
if let Ok(dev) = RawDevice::open(&path) {
|
||||
return Some(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
mod tokio_stream {
|
||||
use super::*;
|
||||
|
|
|
@ -35,18 +35,22 @@ impl Device {
|
|||
Self::_open(path.as_ref())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _open(path: &Path) -> io::Result<Device> {
|
||||
let raw = RawDevice::open(path)?;
|
||||
RawDevice::open(path).map(Self::from_raw_device)
|
||||
}
|
||||
|
||||
// TODO: should this be public?
|
||||
pub(crate) fn from_raw_device(raw: RawDevice) -> Device {
|
||||
let state = DeviceState::new(&raw);
|
||||
let prev_state = state.clone();
|
||||
|
||||
Ok(Device {
|
||||
Device {
|
||||
raw,
|
||||
prev_state,
|
||||
state,
|
||||
block_dropped: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the synchronization engine's current understanding (cache) of the device state.
|
||||
|
|
Loading…
Reference in a new issue