Skip to content

Commit 084b739

Browse files
committed
feat!: Extend the API to provide access to the mDNS information
1 parent 3a3fb5e commit 084b739

File tree

3 files changed

+72
-16
lines changed

3 files changed

+72
-16
lines changed

examples/list.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use futures_util::StreamExt;
44
use serde::{Deserialize, Serialize};
55
use tracing::{info, trace, warn};
66
use tracing_subscriber::EnvFilter;
7-
use wot_discovery::Discoverer;
7+
use wot_discovery::{Discovered, Discoverer};
88
use wot_td::extend::ExtendableThing;
99

1010
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -33,9 +33,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
3333
let d = Discoverer::new()?.ext::<A>();
3434

3535
d.stream()?
36-
.for_each(|thing| {
37-
match thing {
38-
Ok(t) => {
36+
.for_each(|discovered| {
37+
match discovered {
38+
Ok(Discovered { thing: t, .. }) => {
3939
info!("found {:?} {:?}", t.title, t.id,);
4040
trace!("{}", serde_json::to_string_pretty(&t).unwrap());
4141
}

src/lib.rs

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//!
77
//! - [x] [mDNS-SD (HTTP)](https://www.w3.org/TR/wot-discovery/#introduction-dns-sd-sec)
88
9-
use std::marker::PhantomData;
9+
use std::{marker::PhantomData, net::IpAddr};
1010

1111
use futures_core::Stream;
1212
use futures_util::StreamExt;
@@ -43,25 +43,73 @@ pub struct Discoverer<Other: ExtendableThing + ExtendablePiece = Nil> {
4343
_other: PhantomData<Other>,
4444
}
4545

46+
/// Discovered Thing and its mDNS information
47+
pub struct Discovered<Other: ExtendableThing + ExtendablePiece> {
48+
/// Discovered Thing
49+
///
50+
/// It is provided as presented by the discovered Servient.
51+
pub thing: Thing<Other>,
52+
info: ServiceInfo,
53+
scheme: String,
54+
}
55+
56+
impl<Other: ExtendableThing + ExtendablePiece> Discovered<Other> {
57+
/// Discovered Servient listening addresses
58+
pub fn get_addresses(&self) -> Vec<IpAddr> {
59+
self.info
60+
.get_addresses()
61+
.iter()
62+
.map(|ip| ip.to_owned().into())
63+
.collect()
64+
}
65+
/// Discovered Servient listening port
66+
pub fn get_port(&self) -> u16 {
67+
self.info.get_port()
68+
}
69+
70+
/// Discovered Servient hostname
71+
///
72+
/// To be used to make tls requests
73+
pub fn get_hostname(&self) -> &str {
74+
self.info.get_hostname()
75+
}
76+
77+
/// Discovered Servient scheme
78+
pub fn get_scheme(&self) -> &str {
79+
&self.scheme
80+
}
81+
}
82+
4683
async fn get_thing<Other: ExtendableThing + ExtendablePiece>(
4784
info: ServiceInfo,
48-
) -> Result<Thing<Other>> {
85+
) -> Result<Discovered<Other>> {
4986
let host = info.get_addresses().iter().next().ok_or(Error::NoAddress)?;
5087
let port = info.get_port();
5188
let props = info.get_properties();
5289
let path = props.get_property_val_str("td").unwrap_or(WELL_KNOWN);
53-
let proto = match props.get_property_val_str("tls") {
54-
Some(x) if x == "1" => "https",
55-
_ => "http",
56-
};
90+
let proto = props
91+
.get_property_val_str("scheme")
92+
.or_else(|| {
93+
// compatibility with
94+
props
95+
.get_property_val_str("tls")
96+
.map(|tls| if tls == "1" { "https" } else { "http" })
97+
})
98+
.unwrap_or("http");
5799

58100
debug!("Got {proto} {host} {port} {path}");
59101

60102
let r = reqwest::get(format!("{proto}://{host}:{port}{path}")).await?;
61103

62-
let t = r.json().await?;
104+
let thing = r.json().await?;
105+
let scheme = proto.to_owned();
106+
let d = Discovered {
107+
thing,
108+
info,
109+
scheme,
110+
};
63111

64-
Ok(t)
112+
Ok(d)
65113
}
66114

67115
impl Discoverer {
@@ -98,7 +146,7 @@ impl<Other: ExtendableThing + ExtendablePiece> Discoverer<Other> {
98146
}
99147

100148
/// Returns an Stream of discovered things
101-
pub fn stream(&self) -> Result<impl Stream<Item = Result<Thing<Other>>>> {
149+
pub fn stream(&self) -> Result<impl Stream<Item = Result<Discovered<Other>>>> {
102150
let receiver = self.mdns.browse(&self.service_type)?;
103151

104152
let s = receiver.into_stream().filter_map(|v| async move {

tests/mdns.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,26 @@ async fn discoverer() -> Result<(), Box<dyn std::error::Error>> {
5757
task::spawn_local(async {
5858
let d = Discoverer::new().unwrap();
5959

60-
let t = std::pin::pin!(d.stream().unwrap()).next().await.unwrap()?;
60+
let discovered = std::pin::pin!(d.stream().unwrap()).next().await.unwrap()?;
61+
let hostname = discovered.get_hostname();
62+
let addresses = discovered.get_addresses();
63+
let port = discovered.get_port();
64+
let t = &discovered.thing;
6165

6266
assert_eq!("TestThing", t.title);
63-
println!("Found {}", t.title);
67+
println!(
68+
"Found {} at {} ({:?} : {})",
69+
t.title, hostname, addresses, port
70+
);
6471
Result::<(), Box<dyn std::error::Error>>::Ok(())
6572
})
6673
.await??;
6774

6875
task::spawn_local(async {
6976
let d = Discoverer::new().unwrap().ext::<A>();
7077

71-
let t = std::pin::pin!(d.stream().unwrap()).next().await.unwrap()?;
78+
let discovered = std::pin::pin!(d.stream().unwrap()).next().await.unwrap()?;
79+
let t = &discovered.thing;
7280

7381
assert_eq!("TestThing", t.title);
7482
println!("Found {}", t.title);

0 commit comments

Comments
 (0)