1use crate::{Error, Response};
23use futures_util::{StreamExt, pin_mut, TryFutureExt};
24use std::time::Duration;
25
26pub async fn one<S>(
28 service_name: &str,
29 host_name: S,
30 timeout: Duration,
31) -> Result<Option<Response>, Error>
32where
33 S: AsRef<str>,
34{
35 let stream = crate::discover::all(service_name, timeout * 2)?.listen();
37 pin_mut!(stream);
38
39 let process = async {
40 while let Some(Ok(response)) = stream.next().await {
41 match response.hostname() {
42 Some(found_host) if found_host == host_name.as_ref() => return Some(response),
43 _ => {}
44 }
45 }
46
47 None
48 };
49
50 async_std::future::timeout(timeout, process).map_err(|e| e.into()).await
51}
52
53pub async fn multiple<S>(
55 service_name: &str,
56 host_names: &[S],
57 timeout: Duration,
58) -> Result<Vec<Response>, Error>
59where
60 S: AsRef<str>,
61{
62 let stream = crate::discover::all(service_name, timeout * 2)?.listen();
64 pin_mut!(stream);
65
66 let mut found = Vec::new();
67
68 let process = async {
69 while let Some(Ok(response)) = stream.next().await {
70 match response.hostname() {
71 Some(found_host) if host_names.iter().any(|s| s.as_ref() == found_host) => {
72 found.push(response);
73
74 if found.len() == host_names.len() {
75 return;
76 }
77 }
78 _ => {}
79 }
80 }
81 };
82
83 match async_std::future::timeout(timeout, process).await {
84 Ok(()) => Ok(found),
85 Err(e) => Err(e.into())
86 }
87}