1use std::fmt::{Display, Error, Formatter};
2use std::io;
3use std::iter::{FromIterator, IntoIterator};
4
5use super::{parse_full_domain, parse_host_and_port, parse_proto};
6
7#[derive(Debug, Clone)]
9pub struct Url {
10 pub protocol: String,
12 pub host: String,
14 pub port: String,
16 pub path: String,
18
19 _absolute: String,
20}
21
22impl Display for Url {
23 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
24 write!(f, "url: {},\nproto: {},\nhost: {},\nport: {},\npath: {}\n", self._absolute, self.protocol, self.host, self.port, self.path)
25 }
26}
27
28impl Url {
29 pub fn new(url: &str) -> Self {
30 let url = url.to_string();
31 let (protocol, rest) = parse_proto(url.clone(), None);
32 let (full_domain, path) = parse_full_domain(rest, None);
33 let (host, port) = parse_host_and_port(full_domain, Self::get_default_port_for_proto(&protocol));
34 Url {
35 protocol,
36 host,
37 port,
38 path,
39 _absolute: url,
40 }
41 }
42
43 fn get_default_port_for_proto(proto: &str) -> Option<String> {
44 match proto {
45 "http" => Some("80".to_string()),
46 "https" => Some("443".to_string()),
47 _ => None
48 }
49 }
50
51 pub fn get_full_url(&self) -> String {
53 self.protocol.clone() + "://" + &self.host + ":" + &self.port + &self.path
54 }
55
56 pub fn get_host_with_port(&self) -> String {
58 self.host.clone() + ":" + &self.port
59 }
60}
61
62pub trait ToUrl {
64 fn to_url(&self) -> io::Result<Url>;
65}
66
67
68impl ToUrl for String {
69 fn to_url(&self) -> io::Result<Url> {
70 Ok(Url::new(self))
71 }
72}
73
74impl ToUrl for &str {
75 fn to_url(&self) -> io::Result<Url> {
76 Ok(Url::new(self))
77 }
78}
79
80impl ToUrl for Url {
81 fn to_url(&self) -> io::Result<Url> {
82 Ok(self.clone())
83 }
84}
85
86impl ToUrl for &'_ Url {
87 fn to_url(&self) -> io::Result<Url> {
88 Ok((*self).clone())
89 }
90}
91
92pub struct Tuple<T>
93 where T: Clone {
94 pub left: T,
95 pub right: T,
96}
97
98impl<T> FromIterator<T> for Tuple<T>
99 where T: Clone {
100 fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Tuple<T> {
101 let mut iterator = iter.into_iter();
102 if let Some(left) = iterator.next() {
103 if let Some(right) = iterator.next() {
104 let left = left;
105 let right = right;
106 return Tuple { left, right };
107 }
108 }
109 panic!("not enough elements");
110 }
111}