ice_rs/
proxy_parser.rs

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}