dbus_server_address_parser/decode/
tcp.rs

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