Skip to main content

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}