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
use std::borrow::Cow;
use std::net::Ipv4Addr;
use crate::error::{Result, StartupError};
pub trait ToHostAddress {
fn to_address(&self) -> Result<Ipv4Addr>;
}
impl ToHostAddress for Ipv4Addr {
fn to_address(&self) -> Result<Ipv4Addr> {
Ok(*self)
}
}
impl ToHostAddress for [u8; 4] {
fn to_address(&self) -> Result<Ipv4Addr> {
Ok(Ipv4Addr::new(self[0], self[1], self[2], self[3]))
}
}
impl ToHostAddress for String {
fn to_address(&self) -> Result<Ipv4Addr> {
Ok(Ipv4Addr::from(parse_ip(self)?))
}
}
impl ToHostAddress for &str {
fn to_address(&self) -> Result<Ipv4Addr> {
Ok(Ipv4Addr::from(parse_ip(self)?))
}
}
pub fn parse_ip(raw: &str) -> Result<[u8; 4]> {
if raw == "localhost" {
return Ok([127, 0, 0, 1]);
}
let mut ip = [0; 4];
let split_ip = raw.split('.').collect::<Vec<&str>>();
if split_ip.len() != 4 {
return Err(StartupError::InvalidIp.into());
}
for i in 0..4 {
let octet = split_ip[i]
.parse::<u8>()
.map_err(|_| StartupError::InvalidIp)?;
ip[i] = octet;
}
Ok(ip)
}
pub(crate) fn any_string(any: Box<dyn std::any::Any + Send>) -> Cow<'static, str> {
if let Some(i) = any.downcast_ref::<String>() {
return Cow::Owned(i.to_owned());
}
if let Some(i) = any.downcast_ref::<&str>() {
return Cow::Borrowed(i);
}
Cow::Borrowed("")
}
#[cfg(test)]
mod test {
use crate::error::StartupError;
use super::parse_ip;
#[test]
fn test_parse_ip() {
assert_eq!(parse_ip("123.231.43.3").unwrap(), [123, 231, 43, 3]);
assert_eq!(parse_ip("123.231.43"), Err(StartupError::InvalidIp.into()));
assert_eq!(
parse_ip("256.231.43.3"),
Err(StartupError::InvalidIp.into())
);
}
}