1use regex::Regex;
2
3use crate::core::Parser;
4use crate::utils::Utils;
5
6impl Parser {
7 pub fn port(&self, input: &str) -> Option<u32> {
18 let rest = Utils::substring_after_login(self, input);
19 let position_colon = rest.find(':');
20 if let Some(v) = position_colon {
21 let _before = &rest[..v];
22 let after = &rest[v + 1..];
23 let re = Regex::new("^[0-9]+").unwrap();
24 let caps = re.captures(after);
25 caps.as_ref()?;
26 let caps = caps.unwrap();
27
28 return Some(caps.get(0).unwrap().as_str().trim().parse::<u32>().unwrap());
29 }
30
31 let default_port = match self.scheme(input) {
32 Some((v, _)) => {
33 let (port, _) = self.port_mappings[&v];
34 Some(port)
35 }
36 None => None,
37 };
38 default_port
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn test_port_works_when_typical() {
48 let input = "https://www.example.co.uk:443/blog/article/search?docid=720&hl=en#dayone";
49 let port = Parser::new(None).port(input);
50 assert_eq!(port.unwrap(), 443);
51 }
52
53 #[test]
54 fn test_port_works_when_scheme_and_port_specified() {
55 let input = "ftp://127.0.0.1:21/test";
56 let port = Parser::new(None).port(input);
57 assert_eq!(port.unwrap(), 21);
58 }
59
60 #[test]
61 fn test_port_works_when_no_path() {
62 let input = "https://www.example.co.uk:443";
63 let port = Parser::new(None).port(input);
64 assert_eq!(port.unwrap(), 443);
65 }
66 #[test]
67 fn test_port_default_works_when_https() {
68 let input = "https://www.example.co.uk";
69 let port = Parser::new(None).port(input);
70 assert_eq!(port.unwrap(), 443);
71 }
72
73 #[test]
74 fn test_port_works_when_default_port_login_and_no_port() {
75 let input =
76 "https://user:pass@www.example.co.uk/blog/article/search?docid=720&hl=en#dayone";
77 let result = Parser::new(None).port(input).unwrap();
78 assert_eq!(result, 443);
79 }
80 #[test]
81 fn test_port_works_when_login_and_no_port() {
82 let input = "user:pass@www.example.co.uk/blog/article/search?docid=720&hl=en#dayone";
83 let result = Parser::new(None).port(input);
84 assert!(result.is_none());
85 }
86
87 #[test]
88 fn test_port_works_when_login_and_no_port_with_numbers() {
89 let input = "user:pass@www.example.co.uk/blog/article/720/test.txt";
90 let result = Parser::new(None).port(input);
91 assert!(result.is_none());
92 }
93
94 #[test]
95 fn test_port_works_when_colon_in_url() {
96 let input = "http://en.wikipedia.org/wiki/Template:Welcome";
97 let result = Parser::new(None).port(input);
98 assert!(result.is_none());
99 }
100}