rupnp/
discovery.rs

1use crate::{Device, Error, Result};
2use futures_util::stream::{Stream, StreamExt, TryStreamExt};
3use ssdp_client::SearchTarget;
4use std::time::Duration;
5
6/// Discovers UPnP devices on the network.
7///
8/// # Example usage:
9/// ```rust,no_run
10/// use futures::prelude::*;
11/// use std::time::Duration;
12/// use rupnp::ssdp::SearchTarget;
13///
14/// # async fn discover() -> Result<(), rupnp::Error> {
15/// let devices = rupnp::discover(&SearchTarget::RootDevice, Duration::from_secs(3)).await?;
16/// pin_utils::pin_mut!(devices);
17///
18/// while let Some(device) = devices.try_next().await? {
19///     println!(
20///         "{} - {} @ {}",
21///         device.device_type(),
22///         device.friendly_name(),
23///         device.url()
24///     );
25/// }
26///
27/// # Ok(())
28/// # }
29/// ```
30// TODO: doc include once stable
31pub async fn discover(
32    search_target: &SearchTarget,
33    timeout: Duration,
34) -> Result<impl Stream<Item = Result<Device>>> {
35    Ok(ssdp_client::search(search_target, timeout, 3, None)
36        .await?
37        .map_err(Error::SSDPError)
38        .map(|res| Ok(res?.location().parse()?))
39        .and_then(Device::from_url))
40}