summaryrefslogtreecommitdiffstats
path: root/crates/common/tedge_config/src/models/ipaddress.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/common/tedge_config/src/models/ipaddress.rs')
-rw-r--r--crates/common/tedge_config/src/models/ipaddress.rs80
1 files changed, 80 insertions, 0 deletions
diff --git a/crates/common/tedge_config/src/models/ipaddress.rs b/crates/common/tedge_config/src/models/ipaddress.rs
new file mode 100644
index 00000000..3c0edc4a
--- /dev/null
+++ b/crates/common/tedge_config/src/models/ipaddress.rs
@@ -0,0 +1,80 @@
+use serde::{Deserialize, Serialize};
+use std::convert::{TryFrom, TryInto};
+use std::fmt;
+use std::net::IpAddr;
+
+#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
+pub struct IpAddress(pub IpAddr);
+
+#[derive(thiserror::Error, Debug)]
+#[error("Invalid ip address: '{input}'.")]
+pub struct InvalidIpAddress {
+ input: String,
+}
+
+impl fmt::Display for IpAddress {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{:?}", self.0)
+ }
+}
+
+impl Default for IpAddress {
+ fn default() -> Self {
+ IpAddress(IpAddr::V4(Ipv4Addr::LOCALHOST))
+ }
+}
+
+impl TryFrom<String> for IpAddress {
+ type Error = InvalidIpAddress;
+
+ fn try_from(input: String) -> Result<Self, Self::Error> {
+ input
+ .parse::<IpAddr>()
+ .map_err(|_| InvalidIpAddress { input })
+ .map(IpAddress)
+ }
+}
+
+impl TryInto<String> for IpAddress {
+ type Error = std::convert::Infallible;
+
+ fn try_into(self) -> Result<String, Self::Error> {
+ Ok(self.to_string())
+ }
+}
+
+impl From<IpAddress> for IpAddr {
+ fn from(val: IpAddress) -> Self {
+ val.0
+ }
+}
+
+#[cfg(test)]
+use assert_matches::*;
+use std::net::Ipv4Addr;
+use std::net::Ipv6Addr;
+
+#[test]
+fn conversion_from_valid_ipv4_succeeds() {
+ let _loh: IpAddress = IpAddress::try_from("127.0.0.1".to_string()).unwrap();
+ assert_matches!(Ipv4Addr::LOCALHOST, _loh);
+}
+
+#[test]
+fn conversion_from_valid_ipv6_succeeds() {
+ let _loh: IpAddress = IpAddress::try_from("::1".to_string()).unwrap();
+ assert_matches!(Ipv6Addr::LOCALHOST, _loh);
+}
+
+#[test]
+fn conversion_from_longer_integer_fails() {
+ assert_matches!(
+ IpAddress::try_from("66000".to_string()),
+ Err(InvalidIpAddress { .. })
+ );
+}
+
+#[test]
+fn conversion_from_ip_to_string() {
+ assert_matches!(TryInto::<String>::try_into(IpAddress(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)))), Ok(ip_str) if ip_str == "::1");
+}