1use std::hash::Hash;
2
3use crate::{errors::*, protocol::{EndPointType, EndpointData}};
4use pest::{Parser, iterators::Pairs};
5
6
7#[derive(Parser)]
8#[grammar = "proxystring.pest"]
9pub struct ProxyParser;
10
11
12
13pub struct DirectProxyData {
14 pub ident: String,
15 pub endpoint: EndPointType,
16}
17
18pub struct IndirectProxyData {
19 pub ident: String,
20 pub adapter: Option<String>,
21}
22
23pub enum ProxyStringType {
24 DirectProxy(DirectProxyData),
25 IndirectProxy(IndirectProxyData)
26}
27
28pub fn parse_proxy_string(proxy_string: &str) -> Result<ProxyStringType, Box<dyn std::error::Error + Sync + Send>> {
29 let result = ProxyParser::parse(Rule::proxystring, proxy_string)?.next().unwrap();
30 for child in result.into_inner() {
31 match child.as_rule() {
32 Rule::direct_proxy => return parse_direct_proxy(child.into_inner()),
33 Rule::indirect_proxy => return parse_indirect_proxy(child.into_inner()),
34 _ => {}
35 }
36 }
37 Err(Box::new(ParsingError::new("Unexpected rule while parsing proxy string.")))
38}
39
40pub fn parse_direct_proxy(rules: Pairs<Rule>) -> Result<ProxyStringType, Box<dyn std::error::Error + Sync + Send>> {
41 let mut ident = "";
42 for child in rules {
43 match child.as_rule() {
44 Rule::ident => {
45 ident = child.as_str();
46 },
47 Rule::endpoint => {
48 return Ok(
49 ProxyStringType::DirectProxy(
50 DirectProxyData {
51 ident: String::from(ident),
52 endpoint: parse_endpoint(child.into_inner())?
53 }
54 )
55 )
56 }
57 _ => {}
58 }
59 }
60 Err(Box::new(ParsingError::new("Unexpected rule while parsing proxy string.")))
61}
62
63pub fn parse_indirect_proxy(rules: Pairs<Rule>) -> Result<ProxyStringType, Box<dyn std::error::Error + Sync + Send>> {
64 let mut ident = "";
65 let mut adapter = None;
66
67 for child in rules {
68 match child.as_rule() {
69 Rule::ident => {
70 ident = child.as_str();
71 },
72 Rule::adapter => {
73 for child in child.into_inner() {
74 match child.as_rule() {
75 Rule::keyword_at => {}
76 Rule::ident => {
77 adapter = Some(child.as_str())
78 },
79 _ => return Err(Box::new(ParsingError::new("Unexpected rule while parsing proxy string.")))
80 }
81 }
82 },
83 _ => return Err(Box::new(ParsingError::new("Unexpected rule while parsing proxy string.")))
84 }
85 }
86
87 Ok(
88 ProxyStringType::IndirectProxy(IndirectProxyData {
89 ident: String::from(ident),
90 adapter: if adapter.is_some() { Some(String::from(adapter.unwrap())) } else { None }
91 })
92 )
93
94}
95
96pub fn parse_endpoint(rules: Pairs<Rule>) -> Result<EndPointType, Box<dyn std::error::Error + Sync + Send>> {
97 let mut protocol = "";
98 let mut host = "";
99 let mut port = 0i32;
100
101 for child in rules {
102 match child.as_rule() {
103 Rule::endpoint_protocol => {
104 protocol = child.as_str();
105 }
106 Rule::endpoint_host | Rule::endpoint_port => {
107 for item in child.into_inner() {
108 match item.as_rule() {
109 Rule::hostname | Rule::ip => {
110 host = item.as_str();
111 }
112 Rule::port => {
113 port = item.as_str().parse()?;
114 }
115 _ => return Err(Box::new(ParsingError::new(&format!("Unexpected proxy string rule: {:?}", item.as_rule()))))
116 };
117 }
118 }
119 _ => return Err(Box::new(ParsingError::new("Unexpected rule while parsing proxy string.")))
120 }
121 }
122
123 let endpoint_data = EndpointData {
124 host: String::from(host),
125 port,
126 timeout: 60000,
127 compress: false
128 };
129
130 match protocol {
131 "tcp" | "default" => return Ok(EndPointType::TCP(endpoint_data)),
132 "ssl" => return Ok(EndPointType::SSL(endpoint_data)),
133 _ => return Err(Box::new(ParsingError::new("Unsupported protocol.")))
134 }
135}