proxy_scraper/trojan.rs
1use regex::Regex;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5/// Represents a Trojan proxy.
6#[derive(Debug, Serialize, Deserialize)]
7pub struct Trojan {
8 /// The host address of the Trojan proxy.
9 pub host: String,
10 /// The port number for the Trojan proxy.
11 pub port: u32,
12 /// The password associated with the Trojan proxy.
13 pub password: String,
14 /// Additional parameters associated with the Trojan proxy.
15 #[serde(flatten)]
16 pub parameters: Option<HashMap<String, String>>,
17}
18
19impl Trojan {
20 /// Converts the Trojan proxy information into a Trojan URL.
21 ///
22 /// # Example
23 ///
24 /// ```
25 /// use std::collections::HashMap;
26 /// use proxy_scraper::trojan::Trojan;
27 /// let proxy = Trojan {
28 /// host: "example.com".to_string(),
29 /// port: 443,
30 /// password: "password123".to_string(),
31 /// parameters: Some(HashMap::new()), // Insert additional parameters here
32 /// };
33 /// let url = proxy.to_url();
34 /// assert_eq!(url, "trojan://password123@example.com:443?");
35 /// ```
36 pub fn to_url(&self) -> String {
37 let url_encoded_parameters = serde_urlencoded::to_string(&self.parameters).unwrap();
38 format!(
39 "trojan://{}@{}:{}?{}",
40 self.password, self.host, self.port, url_encoded_parameters
41 )
42 }
43
44 /// Scrapes Trojan proxy information from the provided source string and returns a vector of Trojan instances.
45 ///
46 /// # Arguments
47 ///
48 /// * `source` - A string containing the source code or text from which to extract Trojan proxy information.
49 ///
50 /// # Returns
51 ///
52 /// A vector of `Trojan` instances parsed from the source string.
53 pub fn scrape(source: &str) -> Vec<Self> {
54 let source = crate::utils::seperate_links(source);
55 let mut proxy_list: Vec<Trojan> = Vec::new();
56 let regex = Regex::new(r#"trojan://([A-Za-z0-9\-._~]+)@((.+):(\d+))\?(.+)#"#).unwrap();
57
58 for captures in regex.captures_iter(&source) {
59 let password = captures.get(1).map(|pass| pass.as_str()).unwrap_or("");
60 let host = captures.get(3).map(|host| host.as_str()).unwrap_or("");
61 let port = captures.get(4).map(|port| port.as_str()).unwrap_or("");
62 let url_parameters = captures.get(5).map(|params| params.as_str()).unwrap_or("");
63
64 if password.is_empty()
65 || host.is_empty()
66 || port.is_empty()
67 || url_parameters.is_empty()
68 {
69 continue;
70 }
71
72 let parameters: HashMap<String, String> =
73 serde_urlencoded::from_str(&url_parameters).unwrap();
74
75 let trojan_proxy = Trojan {
76 host: host.to_string(),
77 port: port.parse::<u32>().unwrap_or(0),
78 password: password.to_string(),
79 parameters: Some(parameters),
80 };
81
82 proxy_list.push(trojan_proxy);
83 }
84
85 proxy_list
86 }
87}