use crate::attributes::Attributes;
use crate::byte_str::ByteStr;
use crate::client::name_resolution::Address;
use crate::client::name_resolution::NopResolver;
use crate::client::name_resolution::ResolverBuilder;
use crate::client::name_resolution::Target;
use crate::client::name_resolution::UNIX_NETWORK_TYPE;
use crate::client::name_resolution::global_registry;
pub(crate) fn reg() {
global_registry().add_builder(Box::new(Builder {}));
}
#[derive(Debug)]
struct Builder {}
impl ResolverBuilder for Builder {
fn build(
&self,
target: &super::Target,
options: super::ResolverOptions,
) -> Box<dyn super::Resolver> {
match parse_target(target) {
Ok(addr) => NopResolver::new_with_addr(addr, options),
Err(err) => NopResolver::new_with_err(err, options),
}
}
fn scheme(&self) -> &str {
"unix-abstract"
}
fn is_valid_uri(&self, uri: &super::Target) -> bool {
parse_target(uri).is_ok()
}
fn default_authority(&self, _target: &Target) -> String {
"localhost".to_owned()
}
}
fn parse_target(target: &Target) -> Result<Address, String> {
let host_port = target.authority_host_port();
if !host_port.is_empty() {
return Err(format!("invalid (non-empty) authority: {host_port}"));
}
let addr_string = format!("\0{}", target.path());
Ok(Address {
network_type: UNIX_NETWORK_TYPE,
address: ByteStr::from(addr_string),
attributes: Attributes::new(),
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::client::name_resolution::Endpoint;
use crate::client::name_resolution::ResolverOptions;
use crate::client::name_resolution::test_utils::TestChannelController;
use crate::client::name_resolution::test_utils::TestWorkScheduler;
use crate::rt;
#[tokio::test]
async fn unix_abstract_resolver() {
reg();
let target: Target = "unix-abstract:abstract_name".parse().unwrap();
let (work_scheduler, mut work_rx) = TestWorkScheduler::new_pair();
let opts = ResolverOptions {
authority: "ignored".to_string(),
runtime: rt::default_runtime(),
work_scheduler: work_scheduler.clone(),
};
let builder = global_registry()
.get("unix-abstract")
.expect("scheme not found");
let mut resolver = builder.build(&target, opts);
work_rx.recv().await.unwrap();
let (mut channel_controller, mut update_rx) = TestChannelController::new_pair();
resolver.work(&mut channel_controller);
let update = update_rx.recv().await.unwrap();
let want_endpoint = Endpoint {
addresses: vec![Address {
network_type: UNIX_NETWORK_TYPE,
address: ByteStr::from("\0abstract_name".to_owned()),
..Default::default()
}],
..Default::default()
};
assert_eq!(
update.endpoints,
Ok(vec![want_endpoint]),
"did not receive expected endpoint"
);
}
}