From 6f25e7f1547182b6d1123ec02cba4087c4188f7e Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Fri, 20 Aug 2021 13:37:45 -0400 Subject: [PATCH 01/11] Cleanup ffi mod Signed-off-by: Walker Crouse --- zeroconf/src/ffi/mod.rs | 88 ++++++++++++++++++----------------------- zeroconf/src/lib.rs | 4 +- 2 files changed, 40 insertions(+), 52 deletions(-) diff --git a/zeroconf/src/ffi/mod.rs b/zeroconf/src/ffi/mod.rs index 660ad70..d453a5d 100644 --- a/zeroconf/src/ffi/mod.rs +++ b/zeroconf/src/ffi/mod.rs @@ -1,13 +1,9 @@ //! Utilities related to FFI bindings -use crate::Result; -#[cfg(target_os = "linux")] -use libc::{c_char, in_addr, sockaddr_in}; -use libc::{c_void, fd_set, suseconds_t, time_t, timeval}; -use std::time::Duration; -use std::{mem, ptr}; +use libc::c_void; +use std::ptr; -pub mod c_str; +pub(crate) mod c_str; /// Helper trait to convert a raw `*mut c_void` to it's rust type pub trait FromRaw { @@ -43,36 +39,6 @@ pub trait AsRaw { } } -/// Performs a unix `select()` on the specified `sock_fd` and `timeout`. Returns the select result -/// or `Err` if the result is negative. -/// -/// # Safety -/// This function is unsafe because it directly interfaces with C-library system calls. -pub unsafe fn read_select(sock_fd: i32, timeout: Duration) -> Result { - let mut read_flags: fd_set = mem::zeroed(); - - libc::FD_ZERO(&mut read_flags); - libc::FD_SET(sock_fd, &mut read_flags); - - let tv_sec = timeout.as_secs() as time_t; - let tv_usec = timeout.subsec_micros() as suseconds_t; - let mut timeout = timeval { tv_sec, tv_usec }; - - let result = libc::select( - sock_fd + 1, - &mut read_flags, - ptr::null_mut(), - ptr::null_mut(), - &mut timeout, - ); - - if result < 0 { - Err("select(): returned error status".into()) - } else { - Ok(result as u32) - } -} - /// Helper trait to unwrap a type to a `*const T` or a null-pointer if not present. pub trait UnwrapOrNull { /// Unwraps this type to `*const T` or `ptr::null()` if not present. @@ -97,18 +63,40 @@ impl UnwrapMutOrNull for Option<*mut T> { } } -/// Returns a human-readable address of the specified raw address -/// -/// # Safety -/// This function is unsafe because of calls to C-library system calls -#[cfg(target_os = "linux")] -pub unsafe fn get_ip(address: *const sockaddr_in) -> String { - assert_not_null!(address); - let raw = inet_ntoa(&(*address).sin_addr as *const in_addr); - String::from(c_str::raw_to_str(raw)) -} +#[cfg(target_os = "apple")] +mod macos { + use crate::Result; + use libc::{c_void, fd_set, suseconds_t, time_t, timeval}; + use std::mem; + use std::time::Duration; -#[cfg(target_os = "linux")] -extern "C" { - fn inet_ntoa(addr: *const in_addr) -> *const c_char; + /// Performs a unix `select()` on the specified `sock_fd` and `timeout`. Returns the select result + /// or `Err` if the result is negative. + /// + /// # Safety + /// This function is unsafe because it directly interfaces with C-library system calls. + pub unsafe fn read_select(sock_fd: i32, timeout: Duration) -> Result { + let mut read_flags: fd_set = mem::zeroed(); + + libc::FD_ZERO(&mut read_flags); + libc::FD_SET(sock_fd, &mut read_flags); + + let tv_sec = timeout.as_secs() as time_t; + let tv_usec = timeout.subsec_micros() as suseconds_t; + let mut timeout = timeval { tv_sec, tv_usec }; + + let result = libc::select( + sock_fd + 1, + &mut read_flags, + ptr::null_mut(), + ptr::null_mut(), + &mut timeout, + ); + + if result < 0 { + Err("select(): returned error status".into()) + } else { + Ok(result as u32) + } + } } diff --git a/zeroconf/src/lib.rs b/zeroconf/src/lib.rs index 217a491..336aaaa 100644 --- a/zeroconf/src/lib.rs +++ b/zeroconf/src/lib.rs @@ -133,17 +133,17 @@ extern crate maplit; #[macro_use] mod macros; +mod ffi; mod interface; +mod service_type; #[cfg(test)] mod tests; pub mod browser; pub mod error; pub mod event_loop; -pub mod ffi; pub mod prelude; pub mod service; -pub mod service_type; pub mod txt_record; #[cfg(target_os = "linux")] From 94ae23b554313c6bfb32ecb1dc22e5a4224aea1f Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Fri, 20 Aug 2021 13:43:58 -0400 Subject: [PATCH 02/11] Cleanup ffi mod (apple) Signed-off-by: Walker Crouse --- zeroconf/src/ffi/mod.rs | 8 ++++---- zeroconf/src/macos/event_loop.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/zeroconf/src/ffi/mod.rs b/zeroconf/src/ffi/mod.rs index d453a5d..419e583 100644 --- a/zeroconf/src/ffi/mod.rs +++ b/zeroconf/src/ffi/mod.rs @@ -63,11 +63,11 @@ impl UnwrapMutOrNull for Option<*mut T> { } } -#[cfg(target_os = "apple")] -mod macos { +#[cfg(target_vendor = "apple")] +pub(crate) mod macos { use crate::Result; - use libc::{c_void, fd_set, suseconds_t, time_t, timeval}; - use std::mem; + use libc::{fd_set, suseconds_t, time_t, timeval}; + use std::{mem, ptr}; use std::time::Duration; /// Performs a unix `select()` on the specified `sock_fd` and `timeout`. Returns the select result diff --git a/zeroconf/src/macos/event_loop.rs b/zeroconf/src/macos/event_loop.rs index 9d78d5a..4d36e00 100644 --- a/zeroconf/src/macos/event_loop.rs +++ b/zeroconf/src/macos/event_loop.rs @@ -21,7 +21,7 @@ impl<'a> TEventLoop for BonjourEventLoop<'a> { /// new data, the blocking call is not made. fn poll(&self, timeout: Duration) -> Result<()> { let service = self.service.lock().unwrap(); - let select = unsafe { ffi::read_select(service.sock_fd(), timeout)? }; + let select = unsafe { ffi::macos::read_select(service.sock_fd(), timeout)? }; if select > 0 { service.process_result() } else { From 6a9441cabfde09501698e4b246f86bca6841810b Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Fri, 20 Aug 2021 13:52:04 -0400 Subject: [PATCH 03/11] Use constants from avahi_sys instead of redefining them Signed-off-by: Walker Crouse --- zeroconf/src/ffi/mod.rs | 2 +- zeroconf/src/linux/avahi_util.rs | 7 +++---- zeroconf/src/linux/browser.rs | 7 +++---- zeroconf/src/linux/constants.rs | 5 ----- zeroconf/src/linux/mod.rs | 2 -- zeroconf/src/linux/service.rs | 5 ++--- 6 files changed, 9 insertions(+), 19 deletions(-) delete mode 100644 zeroconf/src/linux/constants.rs diff --git a/zeroconf/src/ffi/mod.rs b/zeroconf/src/ffi/mod.rs index 419e583..8ab9d39 100644 --- a/zeroconf/src/ffi/mod.rs +++ b/zeroconf/src/ffi/mod.rs @@ -67,8 +67,8 @@ impl UnwrapMutOrNull for Option<*mut T> { pub(crate) mod macos { use crate::Result; use libc::{fd_set, suseconds_t, time_t, timeval}; - use std::{mem, ptr}; use std::time::Duration; + use std::{mem, ptr}; /// Performs a unix `select()` on the specified `sock_fd` and `timeout`. Returns the select result /// or `Err` if the result is negative. diff --git a/zeroconf/src/linux/avahi_util.rs b/zeroconf/src/linux/avahi_util.rs index 82d5c68..2b6e9d7 100644 --- a/zeroconf/src/linux/avahi_util.rs +++ b/zeroconf/src/linux/avahi_util.rs @@ -1,6 +1,5 @@ //! Utilities related to Avahi -use super::constants; use crate::NetworkInterface; use avahi_sys::{avahi_address_snprint, avahi_strerror, AvahiAddress}; use libc::c_char; @@ -16,11 +15,11 @@ use std::ffi::CStr; pub unsafe fn avahi_address_to_string(addr: *const AvahiAddress) -> String { assert_not_null!(addr); - let addr_str = c_string!(alloc(constants::AVAHI_ADDRESS_STR_MAX)); + let addr_str = c_string!(alloc(avahi_sys::AVAHI_ADDRESS_STR_MAX as usize)); avahi_address_snprint( addr_str.as_ptr() as *mut c_char, - constants::AVAHI_ADDRESS_STR_MAX, + avahi_sys::AVAHI_ADDRESS_STR_MAX as usize, addr, ); @@ -43,7 +42,7 @@ pub fn get_error<'a>(code: i32) -> &'a str { /// [`NetworkInterface`]: ../../enum.NetworkInterface.html pub fn interface_index(interface: NetworkInterface) -> i32 { match interface { - NetworkInterface::Unspec => constants::AVAHI_IF_UNSPEC, + NetworkInterface::Unspec => avahi_sys::AVAHI_IF_UNSPEC, NetworkInterface::AtIndex(i) => i as i32, } } diff --git a/zeroconf/src/linux/browser.rs b/zeroconf/src/linux/browser.rs index ae7c703..3a42fbb 100644 --- a/zeroconf/src/linux/browser.rs +++ b/zeroconf/src/linux/browser.rs @@ -2,7 +2,6 @@ use super::avahi_util; use super::client::{ManagedAvahiClient, ManagedAvahiClientParams}; -use super::constants; use super::poll::ManagedAvahiSimplePoll; use super::raw_browser::{ManagedAvahiServiceBrowser, ManagedAvahiServiceBrowserParams}; use super::{ @@ -48,7 +47,7 @@ impl TMdnsBrowser for AvahiMdnsBrowser { browser: None, kind: c_string!(service_type.to_string()), context: Box::into_raw(Box::default()), - interface_index: constants::AVAHI_IF_UNSPEC, + interface_index: avahi_sys::AVAHI_IF_UNSPEC, } } @@ -88,7 +87,7 @@ impl TMdnsBrowser for AvahiMdnsBrowser { ManagedAvahiServiceBrowserParams::builder() .client(&(*self.context).client.as_ref().unwrap()) .interface(self.interface_index) - .protocol(constants::AVAHI_PROTO_UNSPEC) + .protocol(avahi_sys::AVAHI_PROTO_UNSPEC) .kind(self.kind.as_ptr()) .domain(ptr::null_mut()) .flags(0) @@ -191,7 +190,7 @@ fn handle_browser_new( .name(name) .kind(kind) .domain(domain) - .aprotocol(constants::AVAHI_PROTO_UNSPEC) + .aprotocol(avahi_sys::AVAHI_PROTO_UNSPEC) .flags(0) .callback(Some(resolve_callback)) .userdata(raw_context) diff --git a/zeroconf/src/linux/constants.rs b/zeroconf/src/linux/constants.rs deleted file mode 100644 index 58aef8c..0000000 --- a/zeroconf/src/linux/constants.rs +++ /dev/null @@ -1,5 +0,0 @@ -use avahi_sys::{AvahiIfIndex, AvahiProtocol}; - -pub const AVAHI_IF_UNSPEC: AvahiIfIndex = -1; -pub const AVAHI_PROTO_UNSPEC: AvahiProtocol = -1; -pub const AVAHI_ADDRESS_STR_MAX: usize = 40; diff --git a/zeroconf/src/linux/mod.rs b/zeroconf/src/linux/mod.rs index 63de996..1783faf 100644 --- a/zeroconf/src/linux/mod.rs +++ b/zeroconf/src/linux/mod.rs @@ -6,8 +6,6 @@ //! [Bonjour]: https://en.wikipedia.org/wiki/Bonjour_(software) //! [Avahi]: https://en.wikipedia.org/wiki/Avahi_(software) -pub(crate) mod constants; - pub mod avahi_util; pub mod browser; pub mod client; diff --git a/zeroconf/src/linux/service.rs b/zeroconf/src/linux/service.rs index 7ae2361..f09c8d9 100644 --- a/zeroconf/src/linux/service.rs +++ b/zeroconf/src/linux/service.rs @@ -2,7 +2,6 @@ use super::avahi_util; use super::client::{self, ManagedAvahiClient, ManagedAvahiClientParams}; -use super::constants; use super::entry_group::{AddServiceParams, ManagedAvahiEntryGroup, ManagedAvahiEntryGroupParams}; use super::poll::ManagedAvahiSimplePoll; use crate::ffi::{c_str, AsRaw, FromRaw, UnwrapOrNull}; @@ -121,7 +120,7 @@ impl AvahiServiceContext { port, group: None, txt_record: None, - interface_index: constants::AVAHI_IF_UNSPEC, + interface_index: avahi_sys::AVAHI_IF_UNSPEC, domain: None, host: None, registered_callback: None, @@ -203,7 +202,7 @@ unsafe fn create_service( group.add_service( AddServiceParams::builder() .interface(context.interface_index) - .protocol(constants::AVAHI_PROTO_UNSPEC) + .protocol(avahi_sys::AVAHI_PROTO_UNSPEC) .flags(0) .name(context.name.as_ref().unwrap().as_ptr()) .kind(context.kind.as_ptr()) From 562dd5497c9affb23167410e9d2437bc4095c0b3 Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Fri, 20 Aug 2021 13:55:06 -0400 Subject: [PATCH 04/11] Panic if no callback is set Signed-off-by: Walker Crouse --- zeroconf/src/linux/browser.rs | 2 +- zeroconf/src/linux/service.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/zeroconf/src/linux/browser.rs b/zeroconf/src/linux/browser.rs index 3a42fbb..22a9f45 100644 --- a/zeroconf/src/linux/browser.rs +++ b/zeroconf/src/linux/browser.rs @@ -122,7 +122,7 @@ impl AvahiBrowserContext { if let Some(f) = &self.service_discovered_callback { f(result, self.user_context.clone()); } else { - warn!("attempted to invoke callback but none was set"); + panic!("attempted to invoke browser callback but none was set"); } } } diff --git a/zeroconf/src/linux/service.rs b/zeroconf/src/linux/service.rs index f09c8d9..a875c69 100644 --- a/zeroconf/src/linux/service.rs +++ b/zeroconf/src/linux/service.rs @@ -132,7 +132,7 @@ impl AvahiServiceContext { if let Some(f) = &self.registered_callback { f(result, self.user_context.clone()); } else { - warn!("attempted to invoke callback but none was set"); + panic!("attempted to invoke service callback but none was set"); } } } From 5517e9e4e4aac34494f4654bdafc0d443b0c4b97 Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Fri, 20 Aug 2021 14:02:36 -0400 Subject: [PATCH 05/11] Improve TxtRecord debug output Signed-off-by: Walker Crouse --- zeroconf/src/linux/txt_record.rs | 1 - zeroconf/src/macos/txt_record.rs | 2 +- zeroconf/src/txt_record.rs | 12 ++++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/zeroconf/src/linux/txt_record.rs b/zeroconf/src/linux/txt_record.rs index 82dc5f1..3464642 100644 --- a/zeroconf/src/linux/txt_record.rs +++ b/zeroconf/src/linux/txt_record.rs @@ -6,7 +6,6 @@ use crate::Result; use libc::c_char; use std::cell::UnsafeCell; -#[derive(Debug)] pub struct AvahiTxtRecord(UnsafeCell); impl TTxtRecord for AvahiTxtRecord { diff --git a/zeroconf/src/macos/txt_record.rs b/zeroconf/src/macos/txt_record.rs index e78a3b3..a77d864 100644 --- a/zeroconf/src/macos/txt_record.rs +++ b/zeroconf/src/macos/txt_record.rs @@ -9,7 +9,7 @@ use std::ffi::CString; use std::{mem, ptr}; /// Interface for interfacting with Bonjour's TXT record capabilities. -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct BonjourTxtRecord(pub(crate) ManagedTXTRecordRef); impl TTxtRecord for BonjourTxtRecord { diff --git a/zeroconf/src/txt_record.rs b/zeroconf/src/txt_record.rs index de3cfc3..1fc6a29 100644 --- a/zeroconf/src/txt_record.rs +++ b/zeroconf/src/txt_record.rs @@ -5,11 +5,11 @@ use serde::de::{MapAccess, Visitor}; use serde::ser::SerializeMap; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::collections::HashMap; -use std::fmt; +use std::fmt::{self, Debug}; use std::marker::PhantomData; /// Interface for interacting with underlying mDNS implementation TXT record capabilities -pub trait TTxtRecord: Clone + PartialEq + Eq { +pub trait TTxtRecord: Clone + PartialEq + Eq + Debug { /// Constructs a new TXT record fn new() -> Self; @@ -130,6 +130,14 @@ impl<'de> Deserialize<'de> for TxtRecord { } } +impl Debug for TxtRecord { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TxtRecord") + .field("data", &self.to_map()) + .finish() + } +} + #[cfg(test)] mod tests { use super::*; From 9cff955915a3fc858740d57674964dab14dda42d Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Fri, 20 Aug 2021 14:19:13 -0400 Subject: [PATCH 06/11] Minor cleanup in linux mod Signed-off-by: Walker Crouse --- zeroconf/src/linux/client.rs | 8 ++++++-- zeroconf/src/linux/entry_group.rs | 2 +- zeroconf/src/linux/poll.rs | 6 +++++- zeroconf/src/linux/raw_browser.rs | 9 ++++++++- zeroconf/src/linux/resolver.rs | 10 +++++++++- zeroconf/src/linux/string_list.rs | 8 ++++++-- 6 files changed, 35 insertions(+), 8 deletions(-) diff --git a/zeroconf/src/linux/client.rs b/zeroconf/src/linux/client.rs index 0b0ff98..c16fddb 100644 --- a/zeroconf/src/linux/client.rs +++ b/zeroconf/src/linux/client.rs @@ -15,7 +15,7 @@ use libc::{c_int, c_void}; /// This struct allocates a new `*mut AvahiClient` when `ManagedAvahiClient::new()` is invoked and /// calls the Avahi function responsible for freeing the client on `trait Drop`. #[derive(Debug)] -pub struct ManagedAvahiClient(pub(super) *mut AvahiClient); +pub struct ManagedAvahiClient(*mut AvahiClient); impl ManagedAvahiClient { /// Initializes the underlying `*mut AvahiClient` and verifies it was created; returning @@ -32,7 +32,7 @@ impl ManagedAvahiClient { let client = unsafe { avahi_client_new( - avahi_simple_poll_get(poll.0), + avahi_simple_poll_get(poll.inner()), flags, callback, userdata, @@ -60,6 +60,10 @@ impl ManagedAvahiClient { pub fn host_name<'a>(&self) -> Result<&'a str> { unsafe { get_host_name(self.0) } } + + pub(super) fn inner(&self) -> *mut AvahiClient { + self.0 + } } impl Drop for ManagedAvahiClient { diff --git a/zeroconf/src/linux/entry_group.rs b/zeroconf/src/linux/entry_group.rs index 53d302e..ba6836b 100644 --- a/zeroconf/src/linux/entry_group.rs +++ b/zeroconf/src/linux/entry_group.rs @@ -72,7 +72,7 @@ impl ManagedAvahiEntryGroup { domain, host, port, - txt.map(|t| t.0).unwrap_mut_or_null() + txt.map(|t| t.inner()).unwrap_mut_or_null() ), "could not register service" )?; diff --git a/zeroconf/src/linux/poll.rs b/zeroconf/src/linux/poll.rs index acb6f9b..2cef826 100644 --- a/zeroconf/src/linux/poll.rs +++ b/zeroconf/src/linux/poll.rs @@ -11,7 +11,7 @@ use avahi_sys::{ /// This struct allocates a new `*mut AvahiSimplePoll` when `ManagedAvahiClient::new()` is invoked /// and calls the Avahi function responsible for freeing the poll on `trait Drop`. #[derive(Debug)] -pub struct ManagedAvahiSimplePoll(pub(super) *mut AvahiSimplePoll); +pub struct ManagedAvahiSimplePoll(*mut AvahiSimplePoll); impl ManagedAvahiSimplePoll { /// Initializes the underlying `*mut AvahiSimplePoll` and verifies it was created; returning @@ -41,6 +41,10 @@ impl ManagedAvahiSimplePoll { pub fn iterate(&self, sleep_time: i32) { unsafe { avahi_simple_poll_iterate(self.0, sleep_time) }; } + + pub(super) fn inner(&self) -> *mut AvahiSimplePoll { + self.0 + } } impl Drop for ManagedAvahiSimplePoll { diff --git a/zeroconf/src/linux/raw_browser.rs b/zeroconf/src/linux/raw_browser.rs index f079ffe..e8ed068 100644 --- a/zeroconf/src/linux/raw_browser.rs +++ b/zeroconf/src/linux/raw_browser.rs @@ -32,7 +32,14 @@ impl ManagedAvahiServiceBrowser { ) -> Result { let browser = unsafe { avahi_service_browser_new( - client.0, interface, protocol, kind, domain, flags, callback, userdata, + client.inner(), + interface, + protocol, + kind, + domain, + flags, + callback, + userdata, ) }; diff --git a/zeroconf/src/linux/resolver.rs b/zeroconf/src/linux/resolver.rs index 6fc6e9e..95c57dc 100644 --- a/zeroconf/src/linux/resolver.rs +++ b/zeroconf/src/linux/resolver.rs @@ -36,7 +36,15 @@ impl ManagedAvahiServiceResolver { ) -> Result { let resolver = unsafe { avahi_service_resolver_new( - client.0, interface, protocol, name, kind, domain, aprotocol, flags, callback, + client.inner(), + interface, + protocol, + name, + kind, + domain, + aprotocol, + flags, + callback, userdata, ) }; diff --git a/zeroconf/src/linux/string_list.rs b/zeroconf/src/linux/string_list.rs index b2fe458..d0b9e99 100644 --- a/zeroconf/src/linux/string_list.rs +++ b/zeroconf/src/linux/string_list.rs @@ -15,7 +15,7 @@ use std::ptr; /// /// `zeroconf::TxtRecord` provides the cross-platform bindings for this functionality. #[derive(Debug)] -pub struct ManagedAvahiStringList(pub(crate) *mut AvahiStringList); +pub struct ManagedAvahiStringList(*mut AvahiStringList); impl ManagedAvahiStringList { /// Creates a new empty TXT record @@ -69,9 +69,13 @@ impl ManagedAvahiStringList { AvahiStringListNode::new(self.0) } - pub(crate) fn clone_raw(raw: *mut AvahiStringList) -> Self { + pub(super) fn clone_raw(raw: *mut AvahiStringList) -> Self { Self(unsafe { avahi_string_list_copy(raw) }) } + + pub(super) fn inner(&self) -> *mut AvahiStringList { + self.0 + } } impl Clone for ManagedAvahiStringList { From 4bd53f33be49895d45bbd725db8622fb1a1a9010 Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Fri, 20 Aug 2021 14:30:45 -0400 Subject: [PATCH 07/11] Minor cleanup for macos mod Signed-off-by: Walker Crouse --- zeroconf/src/macos/service.rs | 4 ++-- zeroconf/src/macos/txt_record.rs | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/zeroconf/src/macos/service.rs b/zeroconf/src/macos/service.rs index cedab4a..e5b5a74 100644 --- a/zeroconf/src/macos/service.rs +++ b/zeroconf/src/macos/service.rs @@ -80,13 +80,13 @@ impl TMdnsService for BonjourMdnsService { let txt_len = self .txt_record .as_ref() - .map(|t| t.0.get_length()) + .map(|t| t.inner().get_length()) .unwrap_or(0); let txt_record = self .txt_record .as_ref() - .map(|t| t.0.get_bytes_ptr()) + .map(|t| t.inner().get_bytes_ptr()) .unwrap_or_null(); self.service.lock().unwrap().register_service( diff --git a/zeroconf/src/macos/txt_record.rs b/zeroconf/src/macos/txt_record.rs index a77d864..20ca21d 100644 --- a/zeroconf/src/macos/txt_record.rs +++ b/zeroconf/src/macos/txt_record.rs @@ -10,7 +10,7 @@ use std::{mem, ptr}; /// Interface for interfacting with Bonjour's TXT record capabilities. #[derive(Clone)] -pub struct BonjourTxtRecord(pub(crate) ManagedTXTRecordRef); +pub struct BonjourTxtRecord(ManagedTXTRecordRef); impl TTxtRecord for BonjourTxtRecord { fn new() -> Self { @@ -76,6 +76,12 @@ impl TTxtRecord for BonjourTxtRecord { } } +impl BonjourTxtRecord { + pub(super) fn inner(&self) -> &ManagedTXTRecordRef { + &self.0 + } +} + impl From for BonjourTxtRecord { fn from(txt: ManagedTXTRecordRef) -> Self { Self(txt) From c0dbc9f22d2a4050f7242052d4aafcc6550df009 Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Fri, 20 Aug 2021 14:58:13 -0400 Subject: [PATCH 08/11] Add github step to check formatting Signed-off-by: Walker Crouse --- .github/workflows/rust.yml | 32 ++++++++++++++++++-------------- scripts/checkfmt.sh | 3 +++ 2 files changed, 21 insertions(+), 14 deletions(-) create mode 100755 scripts/checkfmt.sh diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4c76d2d..ea4e207 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,9 +2,9 @@ name: Rust on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] env: CARGO_TERM_COLOR: always @@ -13,19 +13,23 @@ jobs: macOS: runs-on: macos-latest steps: - - uses: actions/checkout@v2 - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose + - uses: actions/checkout@v2 + - name: Check formatting + run: ./scripts/checkfmt.sh + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --verbose linux: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Prepare - run: "sudo apt -y install avahi-daemon libavahi-client-dev && sudo systemctl start avahi-daemon.service" - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose + - uses: actions/checkout@v2 + - name: Prepare + run: "sudo apt -y install avahi-daemon libavahi-client-dev && sudo systemctl start avahi-daemon.service" + - name: Check formatting + run: ./scripts/checkfmt.sh + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --verbose diff --git a/scripts/checkfmt.sh b/scripts/checkfmt.sh new file mode 100755 index 0000000..3fdbb52 --- /dev/null +++ b/scripts/checkfmt.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +find examples/browser/src examples/service/src zeroconf/src zeroconf-macros/src -type f -name *.rs -print0 | xargs -0 -n1 rustfmt --check --verbose From 717c910c57a3ad51fa0a9d95fe58ffea31892b24 Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Fri, 20 Aug 2021 15:09:29 -0400 Subject: [PATCH 09/11] Build all packages in GH workflow Signed-off-by: Walker Crouse --- .github/workflows/rust.yml | 4 ++-- scripts/buildall.sh | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100755 scripts/buildall.sh diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index ea4e207..55d92fa 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -17,7 +17,7 @@ jobs: - name: Check formatting run: ./scripts/checkfmt.sh - name: Build - run: cargo build --verbose + run: ./scripts/buildall.sh - name: Run tests run: cargo test --verbose @@ -30,6 +30,6 @@ jobs: - name: Check formatting run: ./scripts/checkfmt.sh - name: Build - run: cargo build --verbose + run: ./scripts/buildall.sh - name: Run tests run: cargo test --verbose diff --git a/scripts/buildall.sh b/scripts/buildall.sh new file mode 100755 index 0000000..6eb9d57 --- /dev/null +++ b/scripts/buildall.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +cargo build --workspace --verbose +( + cd examples + cargo build --workspace --verbose +) From 79e3287db69f3b25b951e40721c50229badf2a56 Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Fri, 20 Aug 2021 15:20:31 -0400 Subject: [PATCH 10/11] Run clippy in workflow Signed-off-by: Walker Crouse --- .github/workflows/rust.yml | 16 +++++++++++----- scripts/buildall.sh | 2 ++ scripts/checkfmt.sh | 2 ++ scripts/lintall.sh | 11 +++++++++++ 4 files changed, 26 insertions(+), 5 deletions(-) create mode 100755 scripts/lintall.sh diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 55d92fa..63ba9ca 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -14,10 +14,14 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v2 - - name: Check formatting - run: ./scripts/checkfmt.sh + - name: Prepare + run: rustup component add clippy - name: Build run: ./scripts/buildall.sh + - name: Check formatting + run: ./scripts/checkfmt.sh + - name: Run clippy + run: ./scripts/lintall.sh - name: Run tests run: cargo test --verbose @@ -26,10 +30,12 @@ jobs: steps: - uses: actions/checkout@v2 - name: Prepare - run: "sudo apt -y install avahi-daemon libavahi-client-dev && sudo systemctl start avahi-daemon.service" - - name: Check formatting - run: ./scripts/checkfmt.sh + run: "rustup component add clippy && sudo apt -y install avahi-daemon libavahi-client-dev && sudo systemctl start avahi-daemon.service" - name: Build run: ./scripts/buildall.sh + - name: Check formatting + run: ./scripts/checkfmt.sh + - name: Run clippy + run: ./scripts/lintall.sh - name: Run tests run: cargo test --verbose diff --git a/scripts/buildall.sh b/scripts/buildall.sh index 6eb9d57..a40ae4f 100755 --- a/scripts/buildall.sh +++ b/scripts/buildall.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -e + cargo build --workspace --verbose ( cd examples diff --git a/scripts/checkfmt.sh b/scripts/checkfmt.sh index 3fdbb52..f772a61 100755 --- a/scripts/checkfmt.sh +++ b/scripts/checkfmt.sh @@ -1,3 +1,5 @@ #!/bin/bash +set -e + find examples/browser/src examples/service/src zeroconf/src zeroconf-macros/src -type f -name *.rs -print0 | xargs -0 -n1 rustfmt --check --verbose diff --git a/scripts/lintall.sh b/scripts/lintall.sh new file mode 100755 index 0000000..906fdad --- /dev/null +++ b/scripts/lintall.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +cargo clippy -- -D warnings +cargo clippy --all-targets --all-features -- -D warnings +( + cd examples + cargo clippy -- -D warnings + cargo clippy --all-targets --all-features -- -D warnings +) From 9acee330897da6cb677f3e34ca9328940c60fdbc Mon Sep 17 00:00:00 2001 From: Walker Crouse Date: Fri, 20 Aug 2021 15:37:47 -0400 Subject: [PATCH 11/11] Fix linting errors Signed-off-by: Walker Crouse --- zeroconf/src/linux/browser.rs | 2 +- zeroconf/src/service_type.rs | 32 ++++++++++++++++---------------- zeroconf/src/tests/mod.rs | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/zeroconf/src/linux/browser.rs b/zeroconf/src/linux/browser.rs index 22a9f45..4f0d818 100644 --- a/zeroconf/src/linux/browser.rs +++ b/zeroconf/src/linux/browser.rs @@ -85,7 +85,7 @@ impl TMdnsBrowser for AvahiMdnsBrowser { self.browser = Some(ManagedAvahiServiceBrowser::new( ManagedAvahiServiceBrowserParams::builder() - .client(&(*self.context).client.as_ref().unwrap()) + .client((*self.context).client.as_ref().unwrap()) .interface(self.interface_index) .protocol(avahi_sys::AVAHI_PROTO_UNSPEC) .kind(self.kind.as_ptr()) diff --git a/zeroconf/src/service_type.rs b/zeroconf/src/service_type.rs index 19547bb..3e5debb 100644 --- a/zeroconf/src/service_type.rs +++ b/zeroconf/src/service_type.rs @@ -36,9 +36,9 @@ impl ServiceType { } fn check_part(part: &str) -> Result<&str> { - if part.contains(".") { + if part.contains('.') { Err("invalid character: .".into()) - } else if part.contains(",") { + } else if part.contains(',') { Err("invalid character: ,".into()) } else if part.is_empty() { Err("cannot be empty".into()) @@ -48,8 +48,8 @@ impl ServiceType { } fn lstrip_underscore(s: &str) -> &str { - if s.starts_with("_") { - &s[1..] + if let Some(stripped) = s.strip_prefix('_') { + stripped } else { s } @@ -75,12 +75,12 @@ impl FromStr for ServiceType { type Err = crate::error::Error; fn from_str(s: &str) -> Result { - let parts: Vec<&str> = s.split(",").collect(); + let parts: Vec<&str> = s.split(',').collect(); if parts.is_empty() { return Err("could not parse ServiceType from string".into()); } - let head: Vec<&str> = parts[0].split(".").collect(); + let head: Vec<&str> = parts[0].split('.').collect(); if head.len() != 2 { return Err("invalid name and protocol".into()); } @@ -90,12 +90,12 @@ impl FromStr for ServiceType { let mut sub_types: Vec<&str> = vec![]; if parts.len() > 1 { - for i in 1..parts.len() { - sub_types.push(Self::lstrip_underscore(parts[i])); + for part in parts.iter().skip(1) { + sub_types.push(Self::lstrip_underscore(part)); } } - Ok(ServiceType::with_sub_types(name, protocol, sub_types)?) + ServiceType::with_sub_types(name, protocol, sub_types) } } @@ -105,17 +105,17 @@ mod tests { #[test] fn new_invalid() { - ServiceType::new(".http", "tcp").expect_err("invalid character: .".into()); - ServiceType::new("http", ".tcp").expect_err("invalid character: .".into()); - ServiceType::new(",http", "tcp").expect_err("invalid character: ,".into()); - ServiceType::new("http", ",tcp").expect_err("invalid character: ,".into()); - ServiceType::new("", "tcp").expect_err("cannot be empty".into()); - ServiceType::new("http", "").expect_err("cannot be empty".into()); + ServiceType::new(".http", "tcp").expect_err("invalid character: ."); + ServiceType::new("http", ".tcp").expect_err("invalid character: ."); + ServiceType::new(",http", "tcp").expect_err("invalid character: ,"); + ServiceType::new("http", ",tcp").expect_err("invalid character: ,"); + ServiceType::new("", "tcp").expect_err("cannot be empty"); + ServiceType::new("http", "").expect_err("cannot be empty"); } #[test] fn must_have_name_and_protocol() { - ServiceType::from_str("_http").expect_err("invalid name and protocol".into()); + ServiceType::from_str("_http").expect_err("invalid name and protocol"); } #[test] diff --git a/zeroconf/src/tests/mod.rs b/zeroconf/src/tests/mod.rs index 26e536e..1bf5ace 100644 --- a/zeroconf/src/tests/mod.rs +++ b/zeroconf/src/tests/mod.rs @@ -3,7 +3,7 @@ use std::sync::Once; static INIT: Once = Once::new(); pub(crate) fn setup() { - INIT.call_once(|| env_logger::init()); + INIT.call_once(env_logger::init); } mod service_test;