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
use std::{borrow::Cow, ffi::OsStr};
use super::{
percent::{decode_percents_os_str, decode_percents_str, EncOsStr},
tcp::TcpFamily,
DBusAddr, Error, KeyValFmt, Result, TransportImpl,
};
/// `nonce-tcp:` D-Bus transport.
///
/// <https://dbus.freedesktop.org/doc/dbus-specification.html#transports-nonce-tcp-sockets>
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct NonceTcp<'a> {
host: Option<Cow<'a, str>>,
bind: Option<Cow<'a, str>>,
port: Option<u16>,
family: Option<TcpFamily>,
noncefile: Option<Cow<'a, OsStr>>,
}
impl<'a> NonceTcp<'a> {
/// If set, the DNS name or IP address.
pub fn host(&self) -> Option<&str> {
self.host.as_ref().map(|v| v.as_ref())
}
/// If set, the listenable address.
///
/// Used in a listenable address to configure the interface on which the server will listen:
/// either the IP address of one of the local machine's interfaces (most commonly `127.0.0.1`),
/// or a DNS name that resolves to one of those IP addresses, or `*` to listen on all interfaces
/// simultaneously.
pub fn bind(&self) -> Option<&str> {
self.bind.as_ref().map(|v| v.as_ref())
}
/// If set, the TCP port.
///
/// The TCP port the server will open. A zero value let the server choose a free port provided
/// from the underlying operating system.
pub fn port(&self) -> Option<u16> {
self.port
}
/// If set, the type of socket family.
pub fn family(&self) -> Option<TcpFamily> {
self.family
}
/// If set, the nonce file location.
///
/// File location containing the secret. This is only meaningful in connectable addresses.
pub fn noncefile(&self) -> Option<&OsStr> {
self.noncefile.as_ref().map(|v| v.as_ref())
}
/// Convert into owned version, with 'static lifetime.
pub fn into_owned(self) -> NonceTcp<'static> {
let Self {
host,
bind,
port,
family,
noncefile,
} = self;
NonceTcp {
host: host.map(|h| h.into_owned().into()),
bind: bind.map(|b| b.into_owned().into()),
port,
family,
noncefile: noncefile.map(|n| n.into_owned().into()),
}
}
}
impl<'a> TransportImpl<'a> for NonceTcp<'a> {
fn for_address(s: &'a DBusAddr<'a>) -> Result<Self> {
let mut res = NonceTcp::default();
for (k, v) in s.key_val_iter() {
match (k, v) {
("host", Some(v)) => {
res.host = Some(decode_percents_str(v)?);
}
("bind", Some(v)) => {
res.bind = Some(decode_percents_str(v)?);
}
("port", Some(v)) => {
res.port = Some(
decode_percents_str(v)?
.parse()
.map_err(|_| Error::InvalidValue("port".into()))?,
);
}
("family", Some(v)) => {
res.family = Some(decode_percents_str(v)?.as_ref().try_into()?);
}
("noncefile", Some(v)) => {
res.noncefile = Some(decode_percents_os_str(v)?);
}
_ => continue,
}
}
Ok(res)
}
fn fmt_key_val<'s: 'b, 'b>(&'s self, kv: KeyValFmt<'b>) -> KeyValFmt<'b> {
kv.add("host", self.host())
.add("bind", self.bind())
.add("port", self.port())
.add("family", self.family())
.add("noncefile", self.noncefile().map(EncOsStr))
}
}