async_dnssd/service/
enumerate_domains.rs1use futures_util::StreamExt;
2use std::{
3 io,
4 os::raw::{
5 c_char,
6 c_void,
7 },
8 pin::Pin,
9 task::{
10 Context,
11 Poll,
12 },
13};
14
15use crate::{
16 cstr,
17 ffi,
18 inner,
19 interface::Interface,
20};
21
22type CallbackStream = crate::stream::ServiceStream<inner::OwnedService, EnumerateResult>;
23
24#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
27pub enum Enumerate {
28 BrowseDomains,
30 RegistrationDomains,
32}
33
34impl From<Enumerate> for ffi::DNSServiceFlags {
35 fn from(e: Enumerate) -> Self {
36 match e {
37 Enumerate::BrowseDomains => ffi::FLAGS_BROWSE_DOMAINS,
38 Enumerate::RegistrationDomains => ffi::FLAGS_REGISTRATION_DOMAINS,
39 }
40 }
41}
42
43bitflags::bitflags! {
44 #[derive(Default)]
46 pub struct EnumeratedFlags: ffi::DNSServiceFlags {
47 const MORE_COMING = ffi::FLAGS_MORE_COMING;
52
53 const ADD = ffi::FLAGS_ADD;
58
59 const DEFAULT = ffi::FLAGS_DEFAULT;
63 }
64}
65
66#[must_use = "streams do nothing unless polled"]
68pub struct EnumerateDomains {
69 stream: crate::fused_err_stream::FusedErrorStream<CallbackStream>,
70}
71
72impl futures_core::Stream for EnumerateDomains {
73 type Item = io::Result<EnumerateResult>;
74
75 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
76 let this = self.get_mut();
77 this.stream.poll_next_unpin(cx)
78 }
79}
80
81#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
85pub struct EnumerateResult {
86 pub flags: EnumeratedFlags,
88 pub interface: Interface,
90 pub domain: String,
92}
93
94unsafe extern "C" fn enumerate_callback(
95 _sd_ref: ffi::DNSServiceRef,
96 flags: ffi::DNSServiceFlags,
97 interface_index: u32,
98 error_code: ffi::DNSServiceErrorType,
99 reply_domain: *const c_char,
100 context: *mut c_void,
101) {
102 unsafe {
103 CallbackStream::run_callback(context, error_code, || {
104 let reply_domain = cstr::from_cstr(reply_domain)?;
105
106 Ok(EnumerateResult {
107 flags: EnumeratedFlags::from_bits_truncate(flags),
108 interface: Interface::from_raw(interface_index),
109 domain: reply_domain.to_string(),
110 })
111 });
112 }
113}
114
115#[doc(alias = "DNSServiceEnumerateDomains")]
119pub fn enumerate_domains(enumerate: Enumerate, interface: Interface) -> EnumerateDomains {
120 crate::init();
121
122 let stream = CallbackStream::new(move |sender| {
123 inner::OwnedService::enumerate_domains(
124 enumerate.into(),
125 interface.into_raw(),
126 Some(enumerate_callback),
127 sender,
128 )
129 })
130 .into();
131
132 EnumerateDomains { stream }
133}