diff --git a/zeroconf/src/browser.rs b/zeroconf/src/browser.rs index c07a71f..6d526a2 100644 --- a/zeroconf/src/browser.rs +++ b/zeroconf/src/browser.rs @@ -1,3 +1,5 @@ +//! Trait definition for cross-platform browser + use crate::{EventLoop, NetworkInterface, Result, ServiceDiscoveredCallback}; use std::any::Any; diff --git a/zeroconf/src/linux/string_list.rs b/zeroconf/src/linux/string_list.rs index 604312e..3aefd6c 100644 --- a/zeroconf/src/linux/string_list.rs +++ b/zeroconf/src/linux/string_list.rs @@ -1,3 +1,5 @@ +//! Low level interface for interacting with `AvahiStringList`. + use crate::ffi::c_str; use avahi_sys::{ avahi_free, avahi_string_list_add_pair, avahi_string_list_copy, avahi_string_list_equal, @@ -9,18 +11,36 @@ use libc::{c_char, c_void}; use std::marker::PhantomData; use std::ptr; +/// Wraps the `AvahiStringList` pointer from the raw Avahi bindings. +/// +/// `zeroconf::TxtRecord` provides the cross-platform bindings for this functionality. #[derive(Debug)] pub struct ManagedAvahiStringList(*mut AvahiStringList); impl ManagedAvahiStringList { + /// Creates a new empty TXT record pub fn new() -> Self { Self(unsafe { avahi_string_list_new(ptr::null()) }) } + /// Delegate function for [`avahi_string_list_add_pair()`]. + /// + /// # Safety + /// This function is unsafe because it provides no guarantees about the given pointers that are + /// dereferenced. + /// + /// [`avahi_string_list_add_pair()`]: https://avahi.org/doxygen/html/strlst_8h.html#a72e1b0f724f0c29b5e3c8792f385223f pub unsafe fn add_pair(&mut self, key: *const c_char, value: *const c_char) { self.0 = avahi_string_list_add_pair(self.0, key, value); } + /// Delegate function for [`avahi_string_list_find()`]. Returns a new `AvahiStringListNode`. + /// + /// # Safety + /// This function is unsafe because it provides no guarantees about the given pointers that are + /// dereferenced. + /// + /// [`avahi_string_list_find()`]: https://avahi.org/doxygen/html/strlst_8h.html#aafc54c009a2a1608b517c15a7cf29944 pub unsafe fn find(&mut self, key: *const c_char) -> Option { let node = avahi_string_list_find(self.0, key); if !node.is_null() { @@ -30,17 +50,24 @@ impl ManagedAvahiStringList { } } - pub fn head(&mut self) -> AvahiStringListNode { - AvahiStringListNode::new(self.0) - } - + /// Delegate function for [`avahi_string_list_length()`]. + /// + /// [`avahi_string_list_length()`]: https://avahi.org/doxygen/html/strlst_8h.html#a806c571b338e882390a180b1360c1456 pub fn length(&self) -> u32 { unsafe { avahi_string_list_length(self.0) } } + /// Delegate function for [`avahi_string_list_to_string()`]. + /// + /// [`avahi_string_list_to_string()`]: https://avahi.org/doxygen/html/strlst_8h.html#a5c4b9ab709f22f7741c165ca3756a78b pub fn to_string(&self) -> AvahiString { unsafe { avahi_string_list_to_string(self.0).into() } } + + /// Returns the first node in the list. + pub fn head(&mut self) -> AvahiStringListNode { + AvahiStringListNode::new(self.0) + } } impl Clone for ManagedAvahiStringList { @@ -69,6 +96,9 @@ impl Drop for ManagedAvahiStringList { } } +/// Represents a node or sub-list in an `AvahiStringList`. This struct is similar to it's parent, +/// but it does not free the `AvahiStringList` once dropped and is bound to the lifetime of it's +/// parent. #[derive(new)] pub struct AvahiStringListNode<'a> { list: *mut AvahiStringList, @@ -76,6 +106,7 @@ pub struct AvahiStringListNode<'a> { } impl<'a> AvahiStringListNode<'a> { + /// Returns the next node in the list, or `None` if last node. pub fn next(self) -> Option> { let next = unsafe { avahi_string_list_get_next(self.list) }; if next.is_null() { @@ -85,6 +116,7 @@ impl<'a> AvahiStringListNode<'a> { } } + /// Returns the `AvahiPair` for this list. pub fn get_pair(&mut self) -> AvahiPair { let mut key: *mut c_char = ptr::null_mut(); let mut value: *mut c_char = ptr::null_mut(); @@ -98,6 +130,7 @@ impl<'a> AvahiStringListNode<'a> { } } +/// Represents a key-value pair in an `AvahiStringList`. #[derive(new, Getters)] pub struct AvahiPair { key: AvahiString, @@ -105,10 +138,13 @@ pub struct AvahiPair { value_size: usize, } +/// Represents a string value returned by `AvahiStringList`. The underlying `*mut c_char` is freed +/// using the appropriate Avahi function. #[derive(new)] pub struct AvahiString(*mut c_char); impl AvahiString { + /// Returns this `AvahiStr` as a `&str` or `None` if null. pub fn as_str(&self) -> Option<&str> { if self.0.is_null() { None diff --git a/zeroconf/src/macos/browser.rs b/zeroconf/src/macos/browser.rs index 01d3546..10352a6 100644 --- a/zeroconf/src/macos/browser.rs +++ b/zeroconf/src/macos/browser.rs @@ -2,6 +2,7 @@ use super::service_ref::{ BrowseServicesParams, GetAddressInfoParams, ManagedDNSServiceRef, ServiceResolveParams, }; use super::{bonjour_util, constants}; +use crate::browser::TMdnsBrowser; use crate::builder::BuilderDelegate; use crate::ffi::{self, c_str, AsRaw, FromRaw}; use crate::{EventLoop, NetworkInterface, Result}; @@ -23,10 +24,8 @@ pub struct BonjourMdnsBrowser { context: *mut BonjourBrowserContext, } -impl BonjourMdnsBrowser { - /// Creates a new `BonjourMdnsBrowser` that browses for the specified `kind` - /// (e.g. `_http._tcp`). - pub fn new(kind: &str) -> Self { +impl TMdnsBrowser for BonjourMdnsBrowser { + fn new(kind: &str) -> Self { Self { service: Arc::default(), kind: c_string!(kind), @@ -35,33 +34,22 @@ impl BonjourMdnsBrowser { } } - /// Sets the network interface on which to browse for services on. - /// - /// Most applications will want to use the default value `NetworkInterface::Unspec` to browse - /// on all available interfaces. - pub fn set_network_interface(&mut self, interface: NetworkInterface) { + fn set_network_interface(&mut self, interface: NetworkInterface) { self.interface_index = bonjour_util::interface_index(interface); } - /// Sets the [`ServiceDiscoveredCallback`] that is invoked when the browser has discovered and - /// resolved a service. - /// - /// [`ServiceDiscoveredCallback`]: ../type.ServiceDiscoveredCallback.html - pub fn set_service_discovered_callback( + fn set_service_discovered_callback( &self, service_discovered_callback: Box, ) { unsafe { (*self.context).service_discovered_callback = Some(service_discovered_callback) }; } - /// Sets the optional user context to pass through to the callback. This is useful if you need - /// to share state between pre and post-callback. The context type must implement `Any`. - pub fn set_context(&mut self, context: Box) { + fn set_context(&mut self, context: Box) { unsafe { (*self.context).user_context = Some(Arc::from(context)) }; } - /// Starts the browser. Returns an `EventLoop` which can be called to keep the browser alive. - pub fn browse_services(&mut self) -> Result { + fn browse_services(&mut self) -> Result { debug!("Browsing services: {:?}", self); self.service.lock().unwrap().browse_services( diff --git a/zeroconf/src/macos/txt_record_ref.rs b/zeroconf/src/macos/txt_record_ref.rs index 9c0866b..af1d276 100644 --- a/zeroconf/src/macos/txt_record_ref.rs +++ b/zeroconf/src/macos/txt_record_ref.rs @@ -1,4 +1,4 @@ -//! Low level interface for interacting with `TXTRecordRef` +//! Low level interface for interacting with `TXTRecordRef`. use crate::Result; use bonjour_sys::{ diff --git a/zeroconf/src/prelude.rs b/zeroconf/src/prelude.rs index 49386b1..cd5eb72 100644 --- a/zeroconf/src/prelude.rs +++ b/zeroconf/src/prelude.rs @@ -1,3 +1,5 @@ +//! Crate prelude + pub use crate::browser::TMdnsBrowser; pub use crate::service::TMdnsService; pub use crate::txt_record::TTxtRecord; diff --git a/zeroconf/src/service.rs b/zeroconf/src/service.rs index ba27408..52be252 100644 --- a/zeroconf/src/service.rs +++ b/zeroconf/src/service.rs @@ -1,3 +1,5 @@ +//! Trait definition for cross-platform service. + use crate::{EventLoop, NetworkInterface, Result, ServiceRegisteredCallback, TxtRecord}; use std::any::Any;