dbus_server_address_parser/decode/
nonce_tcp.rs

1use super::{
2    guid::{decode_guid, GuidError},
3    unescape::{unescape, UnescapeError},
4    FamilyError,
5};
6use crate::{Family, NonceTcp};
7use std::convert::TryFrom;
8use std::num::ParseIntError;
9use thiserror::Error;
10
11/// An enum representing all errors, which can occur during decoding a socket address of a
12/// [`nonce-tcp:`]. For example: `nonce-tcp:host=127.0.0.1,port=30900`.
13///
14/// [`nonce-tcp:`]: https://dbus.freedesktop.org/doc/dbus-specification.html#transports-nonce-tcp-sockets
15#[derive(Debug, Clone, Error)]
16pub enum NonceTcpError {
17    #[error("Could not unescape: {0}")]
18    UnescapeError(#[from] UnescapeError),
19    #[error("Port parse: {0}")]
20    PortParseError(#[from] ParseIntError),
21    #[error("GUID error: {0}")]
22    GuidError(#[from] GuidError),
23    #[error("Unknown key")]
24    UnknownKey,
25    #[error("Host is duplicate")]
26    HostDuplicate,
27    #[error("Bind is duplicate")]
28    BindDuplicate,
29    #[error("Port is duplicate")]
30    PortDuplicate,
31    #[error("Family is duplicate")]
32    FamilyDuplicate,
33    #[error("Noncefile is duplicate")]
34    NoncefileDuplicate,
35    #[error("Family decode error")]
36    FamilyError(#[from] FamilyError),
37}
38
39impl NonceTcp {
40    fn decode_host(&mut self, host: &str) -> Result<(), NonceTcpError> {
41        if self.host.is_none() {
42            self.host = Some(unescape(host)?);
43            Ok(())
44        } else {
45            Err(NonceTcpError::HostDuplicate)
46        }
47    }
48
49    fn decode_bind(&mut self, bind: &str) -> Result<(), NonceTcpError> {
50        if self.bind.is_none() {
51            self.bind = Some(unescape(bind)?);
52            Ok(())
53        } else {
54            Err(NonceTcpError::BindDuplicate)
55        }
56    }
57
58    fn decode_port(&mut self, port: &str) -> Result<(), NonceTcpError> {
59        if self.port.is_none() {
60            let port = unescape(port)?.parse()?;
61            self.port = Some(port);
62            Ok(())
63        } else {
64            Err(NonceTcpError::PortDuplicate)
65        }
66    }
67
68    fn decode_family(&mut self, family: &str) -> Result<(), NonceTcpError> {
69        if self.family.is_none() {
70            self.family = Some(Family::try_from(family)?);
71            Ok(())
72        } else {
73            Err(NonceTcpError::FamilyDuplicate)
74        }
75    }
76
77    fn decode_noncefile(&mut self, noncefile: &str) -> Result<(), NonceTcpError> {
78        if self.noncefile.is_none() {
79            let noncefile = unescape(noncefile)?;
80            self.noncefile = Some(noncefile);
81            Ok(())
82        } else {
83            Err(NonceTcpError::NoncefileDuplicate)
84        }
85    }
86
87    fn decode_key_value(&mut self, key_value: &str) -> Result<(), NonceTcpError> {
88        if let Some(host) = key_value.strip_prefix("host=") {
89            self.decode_host(host)
90        } else if let Some(bind) = key_value.strip_prefix("bind=") {
91            self.decode_bind(bind)
92        } else if let Some(port) = key_value.strip_prefix("port=") {
93            self.decode_port(port)
94        } else if let Some(family) = key_value.strip_prefix("family=") {
95            self.decode_family(family)
96        } else if let Some(noncefile) = key_value.strip_prefix("noncefile=") {
97            self.decode_noncefile(noncefile)
98        } else if let Some(guid) = key_value.strip_prefix("guid=") {
99            decode_guid(guid, &mut self.guid)?;
100            Ok(())
101        } else {
102            Err(NonceTcpError::UnknownKey)
103        }
104    }
105}
106
107impl TryFrom<&str> for NonceTcp {
108    type Error = NonceTcpError;
109
110    fn try_from(server_address: &str) -> Result<Self, Self::Error> {
111        let mut tcp = NonceTcp {
112            host: None,
113            bind: None,
114            port: None,
115            family: None,
116            noncefile: None,
117            guid: None,
118        };
119
120        for key_value in server_address.split(',') {
121            tcp.decode_key_value(key_value)?;
122        }
123
124        Ok(tcp)
125    }
126}