#![warn(
anonymous_parameters,
missing_copy_implementations,
missing_debug_implementations,
missing_docs,
nonstandard_style,
rust_2018_idioms,
single_use_lifetimes,
trivial_casts,
trivial_numeric_casts,
unreachable_pub,
unused_extern_crates,
unused_qualifications,
variant_size_differences
)]
#[cfg_attr(target_os = "linux", path = "linux.rs")]
#[cfg_attr(not(target_os = "linux"), path = "mock.rs")]
mod platform;
use std::{cell::Cell, fmt};
use pasts::prelude::*;
use smelling_salts::Device;
enum Kind {
Input(),
Audio(),
Midi(),
Camera(),
}
enum Events {
Read(),
Write(),
All(),
}
struct Platform;
trait Interface {
type Searcher: Notify<Event = Found> + Send + Unpin;
fn searcher(kind: Kind) -> Option<Self::Searcher>;
fn open(found: Found, events: Events) -> Result<Device, Found>;
}
pub struct Searcher(Cell<Option<<Platform as Interface>::Searcher>>);
impl fmt::Debug for Searcher {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Searcher").finish_non_exhaustive()
}
}
impl Searcher {
pub fn with_input() -> Self {
Self(Platform::searcher(Kind::Input()).into())
}
pub fn with_audio() -> Self {
Self(Platform::searcher(Kind::Audio()).into())
}
pub fn with_midi() -> Self {
Self(Platform::searcher(Kind::Midi()).into())
}
pub fn with_camera() -> Self {
Self(Platform::searcher(Kind::Camera()).into())
}
}
impl Notify for Searcher {
type Event = Found;
fn poll_next(mut self: Pin<&mut Self>, task: &mut Task<'_>) -> Poll<Found> {
let Some(ref mut notifier) = self.0.get_mut() else { return Pending };
Pin::new(notifier).poll_next(task)
}
}
pub struct Found(Cell<String>);
impl fmt::Debug for Found {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let path = self.0.take();
f.debug_struct("Found").field("path", &path).finish()?;
self.0.set(path);
Ok(())
}
}
impl Found {
pub fn connect(self) -> Result<Device, Found> {
Platform::open(self, Events::All())
}
pub fn connect_input(self) -> Result<Device, Found> {
Platform::open(self, Events::Read())
}
pub fn connect_output(self) -> Result<Device, Found> {
Platform::open(self, Events::Write())
}
}