1use std::marker::PhantomData;
2
3use bluest::{Adapter, Device};
4use color::ADO_LIGHT_CHARACTERISTIC_UUID;
5use futures::{Stream, StreamExt, TryStreamExt, stream};
6use lightstick::{Connected, Discovered, LightStick};
7use thiserror::Error;
8
9pub mod color;
10pub mod lightstick;
11
12#[derive(Error, Debug)]
13pub enum LightStickErrors {
14 #[error("No adapter exists!")]
15 NoAdapter,
16}
17
18pub async fn scan_for_lightsticks(
25 adapter: &Adapter,
26) -> Result<
27 stream::MapOk<
28 impl Stream<Item = Result<Device, bluest::Error>> + Send + Unpin,
29 impl FnMut(Device) -> LightStick<Discovered>,
30 >,
31 bluest::Error,
32> {
33 let stream = adapter
34 .discover_devices(&[ADO_LIGHT_CHARACTERISTIC_UUID])
35 .await?;
36 Ok(stream.map_ok(|d| LightStick {
37 device: d,
38 adapter: adapter.clone(),
39 _marker: PhantomData::<Discovered>,
40 }))
41}
42
43pub async fn find_first_lightstick(
47 adapter: Option<Adapter>,
48) -> Result<LightStick<Connected>, Box<dyn std::error::Error>> {
49 let adapter = {
51 match adapter {
52 Some(adapter) => adapter,
53 None => {
54 let adapter = Adapter::default().await;
55 match adapter {
56 Some(adapter) => adapter,
57 None => return Err(Box::new(LightStickErrors::NoAdapter)),
58 }
59 }
60 }
61 };
62
63 let mut scan = scan_for_lightsticks(&adapter).await?;
65
66 loop {
68 if let Some(Ok(lightstick)) = scan.next().await {
70 if let Ok(lightstick) = lightstick.connect().await {
72 return Ok(lightstick);
73 }
74 }
75 }
76}
77
78#[cfg(test)]
79mod tests {}