1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use std::net::IpAddr;
use std::sync::Arc;
use std::collections::HashMap;
use futures::{BoxFuture, Future, failed};
use futures::stream::{BoxStream, Stream};
use stream_once::StreamOnce;
use {Name, Address, Error, Resolver, MemResolver, parse_name};
pub struct RouterBuilder(Inner);
#[derive(Clone)]
pub struct Router(Arc<Inner>);
struct Inner {
names: MemResolver,
suffixes: HashMap<String, Box<Resolver>>,
fallback: Option<Box<Resolver>>,
}
impl RouterBuilder {
pub fn new() -> RouterBuilder {
RouterBuilder(Inner {
names: MemResolver::new(),
suffixes: HashMap::new(),
fallback: None,
})
}
pub fn add_ip(&mut self, name: Name, ip: IpAddr) -> &mut Self {
self.0.names.add_host(name, ip);
self
}
pub fn add_suffix<S, R>(&mut self, suffix: S, resolver: R) -> &mut Self
where S: Into<String>, R: Resolver + 'static,
{
self.0.suffixes.insert(suffix.into(), Box::new(resolver));
self
}
pub fn add_default<R>(&mut self, resolver: R) -> &mut Self
where R: Resolver + 'static,
{
self.0.fallback = Some(Box::new(resolver));
self
}
pub fn into_resolver(self) -> Router {
Router(Arc::new(self.0))
}
}
impl Resolver for Router {
fn resolve(&self, name: Name) -> BoxFuture<Address, Error> {
if let Some((host, _)) = parse_name(name) {
if self.0.names.contains_name(host) {
return self.0.names.resolve(name);
}
if let Some(resolver) = self.0.suffixes.get(host) {
return resolver.resolve(name);
} else {
for (idx, _) in host.match_indices('.') {
let suffix = &host[idx+1..];
if let Some(resolver) = self.0.suffixes.get(suffix) {
return resolver.resolve(name);
}
}
if let Some(ref resolver) = self.0.fallback {
return resolver.resolve(name);
}
}
}
failed(Error::NameNotFound).boxed()
}
fn subscribe(&self, name: Name) -> BoxStream<Address, Error> {
if let Some((host, _)) = parse_name(name) {
if self.0.names.contains_name(host) {
return self.0.names.subscribe(name);
}
if let Some(resolver) = self.0.suffixes.get(host) {
return resolver.subscribe(name);
} else {
for (idx, _) in host.match_indices('.') {
let suffix = &host[idx+1..];
if let Some(resolver) = self.0.suffixes.get(suffix) {
return resolver.subscribe(name);
}
}
if let Some(ref resolver) = self.0.fallback {
return resolver.subscribe(name);
}
}
}
StreamOnce::new(failed(Error::NameNotFound)).boxed()
}
}