use std::net::IpAddr;
use crate::{error::Error, sync::SyncUdis, Service, Udis};
#[cfg(feature = "tokio")]
use crate::async_tokio::AsyncUdis;
#[derive(Debug, Clone)]
pub struct Builder {
name: String,
addr: Option<IpAddr>,
services: Vec<Service>,
}
impl Builder {
pub(crate) fn new(name: String) -> Self {
Self {
name,
addr: None,
services: Vec::new(),
}
}
pub fn addr<I>(mut self, ip: I) -> Self
where
I: Into<IpAddr>,
{
self.addr = Some(ip.into());
self
}
pub fn host<S: Into<String>>(mut self, kind: S, port: u16) -> Result<Self, Error> {
let kind = kind.into();
if self.services.iter().any(|s| {
if let Service::Host { kind: k, port: p } = s {
*k == kind || *p == port
} else {
false
}
}) {
Err(Error::DuplicateService { kind, port })
} else {
self.services.push(Service::Host { kind, port });
Ok(self)
}
}
pub fn search<S: Into<String>>(mut self, kind: S) -> Self {
self.services.push(Service::Search { kind: kind.into() });
self
}
pub fn build_sync(self) -> Result<SyncUdis, Error> {
let addr = match self.addr {
Some(addr) => addr,
None => local_ip_address::local_ip()?,
};
Ok(SyncUdis::build(Udis::build(self.name, addr, self.services)))
}
#[cfg(feature = "tokio")]
pub fn build_async(self) -> Result<AsyncUdis, Error> {
let addr = match self.addr {
Some(addr) => addr,
None => local_ip_address::local_ip()?,
};
Ok(AsyncUdis::build(Udis::build(
self.name,
addr,
self.services,
)))
}
}