Merge pull request #14 from windy1/fix/service-type

Fix ServiceType logic
This commit is contained in:
Walker Crouse 2021-08-20 13:22:39 -04:00 committed by GitHub
commit 63ad26ed15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 18 deletions

View File

@ -9,7 +9,7 @@ browse services.
On Linux: On Linux:
```bash ```bash
$ sudo apt install xorg-dev libxcb-shape0-dev libxcb-xfixes0-dev clang $ sudo apt install xorg-dev libxcb-shape0-dev libxcb-xfixes0-dev clang avahi-daemon libavahi-client-dev
``` ```
## TODO ## TODO

2
examples/Cargo.lock generated
View File

@ -502,7 +502,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "zeroconf" name = "zeroconf"
version = "0.8.2" version = "0.9.2"
dependencies = [ dependencies = [
"avahi-sys", "avahi-sys",
"bonjour-sys", "bonjour-sys",

View File

@ -265,10 +265,11 @@ unsafe fn handle_get_address_info(
let hostname = c_str::copy_raw(hostname); let hostname = c_str::copy_raw(hostname);
let domain = bonjour_util::normalize_domain(&ctx.resolved_domain.take().unwrap()); let domain = bonjour_util::normalize_domain(&ctx.resolved_domain.take().unwrap());
let kind = bonjour_util::normalize_domain(&ctx.resolved_kind.take().unwrap());
let result = ServiceDiscovery::builder() let result = ServiceDiscovery::builder()
.name(ctx.resolved_name.take().unwrap()) .name(ctx.resolved_name.take().unwrap())
.service_type(ServiceType::from_str(&ctx.resolved_kind.take().unwrap())?) .service_type(ServiceType::from_str(&kind)?)
.domain(domain) .domain(domain)
.host_name(hostname) .host_name(hostname)
.address(ip) .address(ip)

View File

@ -158,10 +158,11 @@ unsafe fn handle_register(
} }
let domain = bonjour_util::normalize_domain(c_str::raw_to_str(domain)); let domain = bonjour_util::normalize_domain(c_str::raw_to_str(domain));
let kind = bonjour_util::normalize_domain(c_str::raw_to_str(regtype));
let result = ServiceRegistration::builder() let result = ServiceRegistration::builder()
.name(c_str::copy_raw(name)) .name(c_str::copy_raw(name))
.service_type(ServiceType::from_str(&c_str::copy_raw(regtype))?) .service_type(ServiceType::from_str(&kind)?)
.domain(domain) .domain(domain)
.build() .build()
.expect("could not build ServiceRegistration"); .expect("could not build ServiceRegistration");

View File

@ -40,26 +40,40 @@ impl ServiceType {
Err("invalid character: .".into()) Err("invalid character: .".into())
} else if part.contains(",") { } else if part.contains(",") {
Err("invalid character: ,".into()) Err("invalid character: ,".into())
} else if part.is_empty() {
Err("cannot be empty".into())
} else { } else {
Ok(part) Ok(part)
} }
} }
fn lstrip_underscore(s: &str) -> &str {
if s.starts_with("_") {
&s[1..]
} else {
s
}
}
} }
impl ToString for ServiceType { impl ToString for ServiceType {
fn to_string(&self) -> String { fn to_string(&self) -> String {
format!("_{}._{}{}", self.name, self.protocol, { format!(
"_{}._{}{}",
self.name,
self.protocol,
if !self.sub_types.is_empty() { if !self.sub_types.is_empty() {
format!(",_{}", self.sub_types.join(",_")) format!(",_{}", self.sub_types.join(",_"))
} else { } else {
"".to_string() "".to_string()
} }
}) )
} }
} }
impl FromStr for ServiceType { impl FromStr for ServiceType {
type Err = crate::error::Error; type Err = crate::error::Error;
fn from_str(s: &str) -> Result<Self> { fn from_str(s: &str) -> Result<Self> {
let parts: Vec<&str> = s.split(",").collect(); let parts: Vec<&str> = s.split(",").collect();
if parts.is_empty() { if parts.is_empty() {
@ -67,23 +81,17 @@ impl FromStr for ServiceType {
} }
let head: Vec<&str> = parts[0].split(".").collect(); let head: Vec<&str> = parts[0].split(".").collect();
let mut name = head[0]; if head.len() != 2 {
if name.starts_with("_") { return Err("invalid name and protocol".into());
name = &name[1..];
}
let mut protocol = head[1];
if protocol.starts_with("_") {
protocol = &protocol[1..];
} }
let name = Self::lstrip_underscore(head[0]);
let protocol = Self::lstrip_underscore(head[1]);
let mut sub_types: Vec<&str> = vec![]; let mut sub_types: Vec<&str> = vec![];
if parts.len() > 1 { if parts.len() > 1 {
for i in 1..parts.len() { for i in 1..parts.len() {
let mut sub_type = parts[i]; sub_types.push(Self::lstrip_underscore(parts[i]));
if sub_type.starts_with("_") {
sub_type = &sub_type[1..];
}
sub_types.push(sub_type);
} }
} }
@ -101,6 +109,13 @@ mod tests {
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("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());
}
#[test]
fn must_have_name_and_protocol() {
ServiceType::from_str("_http").expect_err("invalid name and protocol".into());
} }
#[test] #[test]