dark_light/stream.rs
1use futures_core::Stream;
2
3use crate::{Error, Mode};
4
5/// Subscribes to theme changes as an async [`Stream`].
6///
7/// This is an adapter over [`crate::subscribe`]. On most platforms it drives the
8/// underlying blocking [`crate::Watcher`] on a background thread and forwards each
9/// [`Mode`] into the returned stream. On `wasm32` (which has no threads here), the
10/// browser's `MediaQueryList` `change` event is forwarded directly instead.
11///
12/// # Example
13///
14/// ``` no_run
15/// use dark_light::{ Error, Mode };
16/// use futures_util::StreamExt;
17///
18/// fn main() -> Result<(), Error> {
19/// futures_executor::block_on(async {
20/// let mut stream = dark_light::stream()?;
21/// while let Some(mode) = stream.next().await {
22/// match mode {
23/// Mode::Dark => {},
24/// Mode::Light => {},
25/// Mode::Unspecified => {},
26/// }
27/// }
28/// Ok(())
29/// })
30/// }
31/// ```
32#[cfg(not(target_arch = "wasm32"))]
33pub fn stream() -> Result<impl Stream<Item = Mode>, Error> {
34 let watcher = crate::subscribe()?;
35 let (tx, rx) = futures_channel::mpsc::unbounded();
36 std::thread::spawn(move || {
37 for mode in watcher.iter() {
38 if tx.unbounded_send(mode).is_err() {
39 break;
40 }
41 }
42 });
43 Ok(rx)
44}
45
46#[cfg(target_arch = "wasm32")]
47pub fn stream() -> Result<impl Stream<Item = Mode>, Error> {
48 crate::platforms::websys::stream()
49}