1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
// Copyright © 2020-2023 The Smelling Salts Contributors.
//
// Licensed under any of:
// - Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
// - Boost Software License, Version 1.0 (https://www.boost.org/LICENSE_1_0.txt)
// - MIT License (https://mit-license.org/)
// At your choosing (See accompanying files LICENSE_APACHE_2_0.txt,
// LICENSE_MIT.txt and LICENSE_BOOST_1_0.txt).
//
//! Abstraction over OS APIs to handle asynchronous device waking.
//!
//! ## Getting Started
//! Most devices are represented as file descriptors on unix-like operating
//! systems (MacOS also has run loops). On Windows, devices are usually sockets
//! or handles. WebAssembly running in the browser doesn't have a equivalent.
//! To get around these device backend differences, Smelling Salts exposed an
//! [`OsDevice`] type which has [`From`] conversions implemented for the
//! platform types.
//!
//! An [`OsDevice`] by itself isn't that useful, though. When you have a handle
//! to a device, you want to asynchronously watch it for events. For this, you
//! construct a [`Device`], which implements [`Notify`](pasts::notify::Notify).
//! But, general devices aren't that useful either, so you'll need to wrap it in
//! your own custom type. Usually, you will filter out some of the events, so
//! you'll need to implement [`Notify`](pasts::notify::Notify).
//!
//! Here's a simple example implementing a [`Notify`](pasts::notify::Notify) for
//! stdin line reading:
//!
//! ```rust,no_run
#![cfg_attr(target_os = "linux", doc = include_str!("../examples/stdin.rs"))]
//! ```
#![doc(
html_logo_url = "https://libcala.github.io/logo.svg",
html_favicon_url = "https://libcala.github.io/icon.svg",
html_root_url = "https://docs.rs/smelling_salts"
)]
#![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
)]
mod device;
mod kind;
mod watch;
#[cfg_attr(target_os = "linux", path = "epoll.rs")]
#[cfg_attr(not(target_os = "linux"), path = "mock.rs")]
mod platform;
pub use self::{device::Device, kind::OsDevice, watch::Watch};
trait Interface {
const WATCH_INPUT: u32;
const WATCH_OUTPUT: u32;
/// Watch a [`DeviceKind`]
fn watch(kind: &kind::DeviceKind, watch: Watch) -> whisk::Channel;
/// Unwatch a [`DeviceKind`]
fn unwatch(kind: &kind::DeviceKind);
}
struct Platform;
impl Platform {
fn watch(kind: &kind::DeviceKind, watch: Watch) -> whisk::Channel {
<Platform as Interface>::watch(kind, watch)
}
fn unwatch(kind: &kind::DeviceKind) {
<Platform as Interface>::unwatch(kind);
}
}