nano_get/url/
models.rs

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/// This is used to represent the various parts of a URL.
8#[derive(Debug, Clone)]
9pub struct Url {
10    /// represents the protocol used in the URL (defaults to http).
11    pub protocol: String,
12    /// represents the Host part of the URL.
13    pub host: String,
14    /// represents the port of the URL (if specified). Default is port 80 for http.
15    pub port: String,
16    /// everything after the / (/ is the default value).
17    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    /// returns the complete url (which was used to create the URL).
52    pub fn get_full_url(&self) -> String {
53        self.protocol.clone() + "://" + &self.host + ":" + &self.port + &self.path
54    }
55
56    /// returns the host:port of the url.
57    pub fn get_host_with_port(&self) -> String {
58        self.host.clone() + ":" + &self.port
59    }
60}
61
62/// Represents the ability to be made into a URL.
63pub 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}