async_dnssd/service/
enumerate_domains.rs1use std::{
2 io,
3 os::raw::{
4 c_char,
5 c_void,
6 },
7 pin::Pin,
8 task::{
9 Context,
10 Poll,
11 },
12};
13
14use crate::{
15 cstr,
16 ffi,
17 inner,
18 interface::Interface,
19};
20
21type CallbackStream = crate::stream::ServiceStream<inner::OwnedService, EnumerateResult>;
22
23#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
26pub enum Enumerate {
27 BrowseDomains,
29 RegistrationDomains,
31}
32
33impl From<Enumerate> for ffi::DNSServiceFlags {
34 fn from(e: Enumerate) -> Self {
35 match e {
36 Enumerate::BrowseDomains => ffi::FLAGS_BROWSE_DOMAINS,
37 Enumerate::RegistrationDomains => ffi::FLAGS_REGISTRATION_DOMAINS,
38 }
39 }
40}
41
42bitflags::bitflags! {
43 #[derive(Default)]
45 pub struct EnumeratedFlags: ffi::DNSServiceFlags {
46 const MORE_COMING = ffi::FLAGS_MORE_COMING;
51
52 const ADD = ffi::FLAGS_ADD;
57
58 const DEFAULT = ffi::FLAGS_DEFAULT;
62 }
63}
64
65#[must_use = "streams do nothing unless polled"]
67pub struct EnumerateDomains {
68 stream: crate::fused_err_stream::FusedErrorStream<CallbackStream>,
69}
70
71impl EnumerateDomains {
72 pin_utils::unsafe_pinned!(stream: crate::fused_err_stream::FusedErrorStream<CallbackStream>);
73}
74
75impl futures_core::Stream for EnumerateDomains {
76 type Item = io::Result<EnumerateResult>;
77
78 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
79 self.stream().poll_next(cx)
80 }
81}
82
83#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
87pub struct EnumerateResult {
88 pub flags: EnumeratedFlags,
90 pub interface: Interface,
92 pub domain: String,
94}
95
96unsafe extern "C" fn enumerate_callback(
97 _sd_ref: ffi::DNSServiceRef,
98 flags: ffi::DNSServiceFlags,
99 interface_index: u32,
100 error_code: ffi::DNSServiceErrorType,
101 reply_domain: *const c_char,
102 context: *mut c_void,
103) {
104 CallbackStream::run_callback(context, error_code, || {
105 let reply_domain = cstr::from_cstr(reply_domain)?;
106
107 Ok(EnumerateResult {
108 flags: EnumeratedFlags::from_bits_truncate(flags),
109 interface: Interface::from_raw(interface_index),
110 domain: reply_domain.to_string(),
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}