Signed-off-by: Walker Crouse <walker.crouse@coop.co.uk>
This commit is contained in:
Walker Crouse 2020-09-28 22:11:30 -04:00
parent 0881c308bd
commit e0fea5b812
13 changed files with 115 additions and 95 deletions

View File

@ -83,6 +83,7 @@ use std::any::Any;
use std::sync::Arc;
use std::time::Duration;
use zeroconf::{MdnsBrowser, ServiceDiscovery};
use zeroconf::prelude::*;
fn main() {
let mut browser = MdnsBrowser::new("_http._tcp");

View File

@ -2,6 +2,7 @@ use std::any::Any;
use std::sync::Arc;
use std::time::Duration;
use zeroconf::{MdnsBrowser, ServiceDiscovery};
use zeroconf::prelude::*;
fn main() {
let mut browser = MdnsBrowser::new("_http._tcp");

29
zeroconf/src/browser.rs Normal file
View File

@ -0,0 +1,29 @@
use crate::{EventLoop, NetworkInterface, Result, ServiceDiscoveredCallback};
use std::any::Any;
pub trait TMdnsBrowser {
/// Creates a new `MdnsBrowser` that browses for the specified `kind` (e.g. `_http._tcp`)
fn new(kind: &str) -> Self;
/// 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.
fn set_network_interface(&mut self, interface: NetworkInterface);
/// Sets the [`ServiceDiscoveredCallback`] that is invoked when the browser has discovered and
/// resolved a service.
///
/// [`ServiceDiscoveredCallback`]: ../type.ServiceDiscoveredCallback.html
fn set_service_discovered_callback(
&mut self,
service_discovered_callback: Box<ServiceDiscoveredCallback>,
);
/// 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`.
fn set_context(&mut self, context: Box<dyn Any>);
/// Starts the browser. Returns an `EventLoop` which can be called to keep the browser alive.
fn browse_services(&mut self) -> Result<EventLoop>;
}

View File

@ -76,6 +76,7 @@
//! use std::sync::Arc;
//! use std::time::Duration;
//! use zeroconf::{MdnsBrowser, ServiceDiscovery};
//! use zeroconf::prelude::*;
//!
//! fn main() {
//! let mut browser = MdnsBrowser::new("_http._tcp");
@ -138,10 +139,12 @@ mod interface;
mod tests;
mod txt_record;
pub mod browser;
pub mod builder;
pub mod error;
pub mod ffi;
pub mod prelude;
pub mod service;
#[cfg(target_os = "linux")]
pub mod linux;

View File

@ -6,6 +6,7 @@ use super::raw_browser::{ManagedAvahiServiceBrowser, ManagedAvahiServiceBrowserP
use super::resolver::{
ManagedAvahiServiceResolver, ManagedAvahiServiceResolverParams, ServiceResolverSet,
};
use crate::browser::TMdnsBrowser;
use crate::builder::BuilderDelegate;
use crate::ffi::{c_str, AsRaw, FromRaw};
use crate::Result;
@ -32,9 +33,8 @@ pub struct AvahiMdnsBrowser {
context: *mut AvahiBrowserContext,
}
impl AvahiMdnsBrowser {
/// Creates a new `AvahiMdnsBrowser` that browses for the specified `kind` (e.g. `_http._tcp`)
pub fn new(kind: &str) -> Self {
impl TMdnsBrowser for AvahiMdnsBrowser {
fn new(kind: &str) -> Self {
Self {
client: None,
poll: None,
@ -45,33 +45,22 @@ impl AvahiMdnsBrowser {
}
}
/// 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 = avahi_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(
&mut self,
service_discovered_callback: Box<ServiceDiscoveredCallback>,
) {
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<dyn Any>) {
fn set_context(&mut self, context: Box<dyn Any>) {
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<EventLoop> {
fn browse_services(&mut self) -> Result<EventLoop> {
debug!("Browsing services: {:?}", self);
self.poll = Some(Arc::new(ManagedAvahiSimplePoll::new()?));

View File

@ -29,7 +29,6 @@ pub struct AvahiMdnsService {
}
impl AvahiMdnsService {
/// Creates a new `AvahiMdnsService` with the specified `kind` (e.g. `_http._tcp`) and `port`.
pub fn new(kind: &str, port: u16) -> Self {
Self {
client: None,
@ -49,51 +48,30 @@ impl AvahiMdnsService {
unsafe { (*self.context).name = Some(c_string!(name)) };
}
/// Sets the network interface to bind this service to.
///
/// Most applications will want to use the default value `NetworkInterface::Unspec` to bind to
/// all available interfaces.
pub fn set_network_interface(&mut self, interface: NetworkInterface) {
unsafe { (*self.context).interface_index = avahi_util::interface_index(interface) };
}
/// Sets the domain on which to advertise the service.
///
/// Most applications will want to use the default value of `ptr::null()` to register to the
/// default domain.
pub fn set_domain(&mut self, _domain: &str) {
todo!()
}
/// Sets the SRV target host name.
///
/// Most applications will want to use the default value of `ptr::null()` to use the machine's
// default host name.
pub fn set_host(&mut self, _host: &str) {
todo!()
}
/// Sets the optional `TxtRecord` to register this service with.
pub fn set_txt_record(&mut self, txt_record: TxtRecord) {
self.txt_record = Some(txt_record);
}
/// Sets the [`ServiceRegisteredCallback`] that is invoked when the service has been
/// registered.
///
/// [`ServiceRegisteredCallback`]: ../type.ServiceRegisteredCallback.html
pub fn set_registered_callback(&mut self, registered_callback: Box<ServiceRegisteredCallback>) {
unsafe { (*self.context).registered_callback = Some(registered_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<dyn Any>) {
unsafe { (*self.context).user_context = Some(Arc::from(context)) };
}
/// Registers and start's the service. Returns an `EventLoop` which can be called to keep
/// the service alive.
pub fn register(&mut self) -> Result<EventLoop> {
debug!("Registering service: {:?}", self);

View File

@ -8,6 +8,7 @@ use std::cell::UnsafeCell;
pub struct AvahiTxtRecord(UnsafeCell<ManagedAvahiStringList>);
impl AvahiTxtRecord {
#[allow(clippy::mut_from_ref)]
fn inner(&self) -> &mut ManagedAvahiStringList {
unsafe { &mut *self.0.get() }
}
@ -98,11 +99,7 @@ impl Iterator for Iter<'_> {
type Item = (String, String);
fn next(&mut self) -> Option<Self::Item> {
if self.node.is_none() {
return None;
}
let mut n = self.node.take().unwrap();
let mut n = self.node.take()?;
let pair = n.get_pair();
self.node = n.next();

View File

@ -3,6 +3,7 @@ use super::{bonjour_util, constants};
use crate::builder::BuilderDelegate;
use crate::ffi::c_str::{self, AsCChars};
use crate::ffi::{FromRaw, UnwrapOrNull};
use crate::service::TMdnsService;
use crate::{
EventLoop, NetworkInterface, Result, ServiceRegisteredCallback, ServiceRegistration, TxtRecord,
};
@ -26,10 +27,8 @@ pub struct BonjourMdnsService {
context: *mut BonjourServiceContext,
}
impl BonjourMdnsService {
/// Creates a new `BonjourMdnsService` with the specified `kind` (e.g. `_http._tcp`) and
/// `port`.
pub fn new(kind: &str, port: u16) -> Self {
impl TMdnsService for BonjourMdnsService {
fn new(kind: &str, port: u16) -> Self {
Self {
service: Arc::default(),
kind: c_string!(kind),
@ -45,56 +44,35 @@ impl BonjourMdnsService {
/// Sets the name to register this service under. If no name is set, Bonjour will
/// automatically assign one (usually to the name of the machine).
pub fn set_name(&mut self, name: &str) {
fn set_name(&mut self, name: &str) {
self.name = Some(c_string!(name));
}
/// Sets the network interface to bind this service to.
///
/// Most applications will want to use the default value `NetworkInterface::Unspec` to bind to
/// 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 domain on which to advertise the service.
///
/// Most applications will want to use the default value of `ptr::null()` to register to the
/// default domain.
pub fn set_domain(&mut self, domain: &str) {
fn set_domain(&mut self, domain: &str) {
self.domain = Some(c_string!(domain));
}
/// Sets the SRV target host name.
///
/// Most applications will want to use the default value of `ptr::null()` to use the machine's
// default host name.
pub fn set_host(&mut self, host: &str) {
fn set_host(&mut self, host: &str) {
self.host = Some(c_string!(host));
}
/// Sets the optional `TxtRecord` to register this service with.
pub fn set_txt_record(&mut self, txt_record: TxtRecord) {
fn set_txt_record(&mut self, txt_record: TxtRecord) {
self.txt_record = Some(txt_record);
}
/// Sets the [`ServiceRegisteredCallback`] that is invoked when the service has been
/// registered.
///
/// [`ServiceRegisteredCallback`]: ../type.ServiceRegisteredCallback.html
pub fn set_registered_callback(&mut self, registered_callback: Box<ServiceRegisteredCallback>) {
fn set_registered_callback(&mut self, registered_callback: Box<ServiceRegisteredCallback>) {
unsafe { (*self.context).registered_callback = Some(registered_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<dyn Any>) {
fn set_context(&mut self, context: Box<dyn Any>) {
unsafe { (*self.context).user_context = Some(Arc::from(context)) };
}
/// Registers and start's the service. Returns an `EventLoop` which can be called to keep
/// the service alive.
pub fn register(&mut self) -> Result<EventLoop> {
fn register(&mut self) -> Result<EventLoop> {
debug!("Registering service: {:?}", self);
let txt_len = self

View File

@ -1 +1,3 @@
pub use crate::browser::TMdnsBrowser;
pub use crate::service::TMdnsService;
pub use crate::txt_record::TTxtRecord;

45
zeroconf/src/service.rs Normal file
View File

@ -0,0 +1,45 @@
use crate::{EventLoop, NetworkInterface, Result, ServiceRegisteredCallback, TxtRecord};
use std::any::Any;
pub trait TMdnsService {
/// Creates a new `MdnsService` with the specified `kind` (e.g. `_http._tcp`) and `port`.
fn new(kind: &str, port: u16) -> Self;
/// Sets the name to register this service under.
fn set_name(&mut self, name: &str);
/// Sets the network interface to bind this service to.
///
/// Most applications will want to use the default value `NetworkInterface::Unspec` to bind to
/// all available interfaces.
fn set_network_interface(&mut self, interface: NetworkInterface);
/// Sets the domain on which to advertise the service.
///
/// Most applications will want to use the default value of `ptr::null()` to register to the
/// default domain.
fn set_domain(&mut self, _domain: &str);
/// Sets the SRV target host name.
///
/// Most applications will want to use the default value of `ptr::null()` to use the machine's
/// default host name.
fn set_host(&mut self, _host: &str);
/// Sets the optional `TxtRecord` to register this service with.
fn set_txt_record(&mut self, txt_record: TxtRecord);
/// Sets the [`ServiceRegisteredCallback`] that is invoked when the service has been
/// registered.
///
/// [`ServiceRegisteredCallback`]: ../type.ServiceRegisteredCallback.html
fn set_registered_callback(&mut self, registered_callback: Box<ServiceRegisteredCallback>);
/// 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`.
fn set_context(&mut self, context: Box<dyn Any>);
/// Registers and start's the service. Returns an `EventLoop` which can be called to keep
/// the service alive.
fn register(&mut self) -> Result<EventLoop>;
}

View File

@ -1,3 +1,4 @@
use crate::prelude::*;
use crate::{MdnsBrowser, MdnsService};
use std::sync::{Arc, Mutex};
use std::time::Duration;

View File

@ -59,8 +59,6 @@ fn iter_success() {
fn keys_success() {
super::setup();
debug!("keys_success()");
let mut record = TxtRecord::new();
record.insert("foo", "bar").unwrap();
record.insert("baz", "qux").unwrap();
@ -76,8 +74,6 @@ fn keys_success() {
fn values_success() {
super::setup();
debug!("values_success()");
let mut record = TxtRecord::new();
record.insert("foo", "bar").unwrap();
record.insert("baz", "qux").unwrap();

View File

@ -80,7 +80,7 @@ impl PartialEq for TxtRecord {
}
}
// impl Eq for TxtRecord {}
impl Eq for TxtRecord {}
impl Default for TxtRecord {
fn default() -> Self {