use std::sync::Arc;
use super::{client::ManagedAvahiClient, string_list::ManagedAvahiStringList};
use crate::Result;
use crate::avahi::avahi_util;
use crate::ffi::UnwrapMutOrNull;
use avahi_sys::{
AvahiClient, AvahiEntryGroup, AvahiEntryGroupCallback, AvahiIfIndex, AvahiProtocol,
AvahiPublishFlags, avahi_client_errno, avahi_entry_group_add_service_strlst,
avahi_entry_group_add_service_subtype, avahi_entry_group_commit, avahi_entry_group_free,
avahi_entry_group_is_empty, avahi_entry_group_new, avahi_entry_group_reset,
};
use libc::{c_char, c_void};
#[derive(Debug)]
pub struct ManagedAvahiEntryGroup {
inner: *mut AvahiEntryGroup,
_client: Arc<ManagedAvahiClient>,
}
impl ManagedAvahiEntryGroup {
pub unsafe fn new(
ManagedAvahiEntryGroupParams {
client,
callback,
userdata,
}: ManagedAvahiEntryGroupParams,
) -> Result<Self> {
let inner = unsafe { avahi_entry_group_new(client.inner, callback, userdata) };
if inner.is_null() {
let err = unsafe { avahi_util::get_error(avahi_client_errno(client.inner)) };
Err(format!("could not initialize AvahiEntryGroup: {}", err).into())
} else {
Ok(Self {
inner,
_client: client,
})
}
}
pub unsafe fn is_empty(&self) -> bool {
unsafe { avahi_entry_group_is_empty(self.inner) != 0 }
}
pub unsafe fn add_service(
&mut self,
AddServiceParams {
interface,
protocol,
flags,
name,
kind,
domain,
host,
port,
txt,
}: AddServiceParams,
) -> Result<()> {
unsafe {
avahi_util::sys_exec(
|| {
avahi_entry_group_add_service_strlst(
self.inner,
interface,
protocol,
flags,
name,
kind,
domain,
host,
port,
txt.map(|t| t.inner()).unwrap_mut_or_null(),
)
},
"could not register service",
)
}
}
pub unsafe fn add_service_subtype(
&mut self,
AddServiceSubtypeParams {
interface,
protocol,
flags,
name,
kind,
domain,
subtype,
}: AddServiceSubtypeParams,
) -> Result<()> {
unsafe {
avahi_util::sys_exec(
|| {
avahi_entry_group_add_service_subtype(
self.inner, interface, protocol, flags, name, kind, domain, subtype,
)
},
"could not register service subtype",
)
}
}
pub unsafe fn commit(&mut self) -> Result<()> {
unsafe {
avahi_util::sys_exec(
|| avahi_entry_group_commit(self.inner),
"could not commit service",
)
}
}
pub unsafe fn reset(&mut self) {
unsafe { avahi_entry_group_reset(self.inner) };
}
pub unsafe fn get_client(&self) -> *mut AvahiClient {
unsafe { avahi_sys::avahi_entry_group_get_client(self.inner) }
}
}
impl Drop for ManagedAvahiEntryGroup {
fn drop(&mut self) {
unsafe { avahi_entry_group_free(self.inner) };
}
}
unsafe impl Send for ManagedAvahiEntryGroup {}
unsafe impl Sync for ManagedAvahiEntryGroup {}
#[derive(Builder, BuilderDelegate)]
pub struct ManagedAvahiEntryGroupParams {
client: Arc<ManagedAvahiClient>,
callback: AvahiEntryGroupCallback,
userdata: *mut c_void,
}
#[derive(Builder, BuilderDelegate)]
pub struct AddServiceParams<'a> {
interface: AvahiIfIndex,
protocol: AvahiProtocol,
flags: AvahiPublishFlags,
name: *const c_char,
kind: *const c_char,
domain: *const c_char,
host: *const c_char,
port: u16,
txt: Option<&'a ManagedAvahiStringList>,
}
#[derive(Builder, BuilderDelegate)]
pub struct AddServiceSubtypeParams {
interface: AvahiIfIndex,
protocol: AvahiProtocol,
flags: AvahiPublishFlags,
name: *const c_char,
kind: *const c_char,
domain: *const c_char,
subtype: *const c_char,
}