libsubconverter/models/
proxy.rs

1//! Proxy model definitions
2//!
3//! Contains the core data structures for proxy configurations.
4
5use std::collections::HashSet;
6
7use super::proxy_node::combined::CombinedProxy;
8
9/// Represents the type of a proxy.
10/// This is the canonical enum used for proxy type identification across the
11/// application.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub enum ProxyType {
14    Unknown,
15    Shadowsocks,
16    ShadowsocksR,
17    VMess,
18    Trojan,
19    Snell,
20    HTTP,
21    HTTPS,
22    Socks5,
23    WireGuard,
24    Hysteria,
25    Hysteria2,
26    // new proxy types could be added as enum combined proxy types
27    Vless,
28    AnyTls,
29}
30
31/// Converts a `ProxyType` into a human-readable name.
32impl ProxyType {
33    pub fn to_string(self) -> &'static str {
34        match self {
35            ProxyType::Shadowsocks => "SS",
36            ProxyType::ShadowsocksR => "SSR",
37            ProxyType::VMess => "VMess",
38            ProxyType::Trojan => "Trojan",
39            ProxyType::Snell => "Snell",
40            ProxyType::HTTP => "HTTP",
41            ProxyType::HTTPS => "HTTPS",
42            ProxyType::Socks5 => "SOCKS5",
43            ProxyType::WireGuard => "WireGuard",
44            ProxyType::Hysteria => "Hysteria",
45            ProxyType::Hysteria2 => "Hysteria2",
46            ProxyType::Vless => "Vless",
47            ProxyType::AnyTls => "AnyTLS",
48            ProxyType::Unknown => "Unknown",
49        }
50    }
51}
52
53/// Represents a proxy configuration.
54#[derive(Debug, Clone)]
55pub struct Proxy {
56    pub proxy_type: ProxyType,
57    pub combined_proxy: Option<CombinedProxy>,
58    pub id: u32,
59    pub group_id: i32,
60    pub group: String,
61    pub remark: String,
62    pub hostname: String,
63    pub port: u16,
64
65    pub username: Option<String>,
66    pub password: Option<String>,
67    pub encrypt_method: Option<String>,
68    pub plugin: Option<String>,
69    /// Plugin options in the format of `key1=value1;key2=value2`
70    pub plugin_option: Option<String>,
71    pub protocol: Option<String>,
72    pub protocol_param: Option<String>,
73    pub obfs: Option<String>,
74    pub obfs_param: Option<String>,
75    pub user_id: Option<String>,
76    pub alter_id: u16,
77    pub transfer_protocol: Option<String>,
78    pub fake_type: Option<String>,
79    pub tls_secure: bool,
80
81    pub host: Option<String>,
82    pub path: Option<String>,
83    pub edge: Option<String>,
84
85    pub quic_secure: Option<String>,
86    pub quic_secret: Option<String>,
87
88    pub udp: Option<bool>,
89    pub tcp_fast_open: Option<bool>,
90    pub allow_insecure: Option<bool>,
91    pub tls13: Option<bool>,
92
93    pub underlying_proxy: Option<String>,
94
95    pub snell_version: u16,
96    pub server_name: Option<String>,
97
98    pub self_ip: Option<String>,
99    pub self_ipv6: Option<String>,
100    pub public_key: Option<String>,
101    pub private_key: Option<String>,
102    pub pre_shared_key: Option<String>,
103    pub dns_servers: HashSet<String>,
104    pub mtu: u16,
105    pub allowed_ips: String,
106    pub keep_alive: u16,
107    pub test_url: Option<String>,
108    pub client_id: Option<String>,
109
110    pub ports: Option<String>,
111    /// upload speed in Mbps
112    pub up_speed: u32,
113    /// download speed in Mbps
114    pub down_speed: u32,
115    pub auth: Option<String>,
116    pub auth_str: Option<String>,
117    pub sni: Option<String>,
118    pub fingerprint: Option<String>,
119    pub ca: Option<String>,
120    pub ca_str: Option<String>,
121    pub recv_window_conn: u32,
122    pub recv_window: u32,
123    pub disable_mtu_discovery: Option<bool>,
124    pub hop_interval: u32,
125    pub alpn: HashSet<String>,
126
127    pub cwnd: u32,
128}
129
130/// Implement Default for Proxy
131impl Default for Proxy {
132    fn default() -> Self {
133        Proxy {
134            proxy_type: ProxyType::Unknown,
135            combined_proxy: None,
136            id: 0,
137            group_id: 0,
138            group: String::new(),
139            remark: String::new(),
140            hostname: String::new(),
141            port: 0,
142            username: None,
143            password: None,
144            encrypt_method: None,
145            plugin: None,
146            plugin_option: None,
147            protocol: None,
148            protocol_param: None,
149            obfs: None,
150            obfs_param: None,
151            user_id: None,
152            alter_id: 0,
153            transfer_protocol: None,
154            fake_type: None,
155            tls_secure: false,
156            host: None,
157            path: None,
158            edge: None,
159            quic_secure: None,
160            quic_secret: None,
161            udp: None,
162            tcp_fast_open: None,
163            allow_insecure: None,
164            tls13: None,
165            underlying_proxy: None,
166            snell_version: 0,
167            server_name: None,
168            self_ip: None,
169            self_ipv6: None,
170            public_key: None,
171            private_key: None,
172            pre_shared_key: None,
173            dns_servers: HashSet::new(),
174            mtu: 0,
175            allowed_ips: String::from("0.0.0.0/0, ::/0"),
176            keep_alive: 0,
177            test_url: None,
178            client_id: None,
179            ports: None,
180            up_speed: 0,
181            down_speed: 0,
182            auth: None,
183            auth_str: None,
184            sni: None,
185            fingerprint: None,
186            ca: None,
187            ca_str: None,
188            recv_window_conn: 0,
189            recv_window: 0,
190            disable_mtu_discovery: None,
191            hop_interval: 0,
192            alpn: HashSet::new(),
193            cwnd: 0,
194        }
195    }
196}
197
198impl Proxy {
199    pub fn is_combined_proxy(&self) -> bool {
200        matches!(
201            self.proxy_type,
202            ProxyType::Vless | ProxyType::Shadowsocks | ProxyType::AnyTls
203        )
204    }
205
206    /// 设置 UDP 支持,如果值已存在则不覆盖
207    pub fn with_udp(mut self, udp: Option<bool>) -> Self {
208        if self.udp.is_none() {
209            self.udp = udp;
210        }
211        self
212    }
213
214    /// 强制设置 UDP 支持,不论是否已存在值
215    pub fn set_udp(mut self, udp: bool) -> Self {
216        self.udp = Some(udp);
217        self
218    }
219
220    /// 设置 TCP Fast Open,如果值已存在则不覆盖
221    pub fn with_tfo(mut self, tfo: Option<bool>) -> Self {
222        if self.tcp_fast_open.is_none() {
223            self.tcp_fast_open = tfo;
224        }
225        self
226    }
227
228    /// 强制设置 TCP Fast Open,不论是否已存在值
229    pub fn set_tfo(mut self, tfo: bool) -> Self {
230        self.tcp_fast_open = Some(tfo);
231        self
232    }
233
234    /// 设置 Skip Cert Verify,如果值已存在则不覆盖
235    pub fn with_skip_cert_verify(mut self, scv: Option<bool>) -> Self {
236        if self.allow_insecure.is_none() {
237            self.allow_insecure = scv;
238        }
239        self
240    }
241
242    /// 强制设置 Skip Cert Verify,不论是否已存在值
243    pub fn set_skip_cert_verify(mut self, scv: bool) -> Self {
244        self.allow_insecure = Some(scv);
245        self
246    }
247
248    /// 设置代理备注
249    pub fn set_remark(mut self, remark: String) -> Self {
250        self.remark = remark;
251        self
252    }
253
254    /// 使用默认值应用 tribool 属性,如果属性值为 None 则设置为提供的默认值
255    pub fn apply_default_values(
256        mut self,
257        default_udp: Option<bool>,
258        default_tfo: Option<bool>,
259        default_scv: Option<bool>,
260    ) -> Self {
261        if self.udp.is_none() {
262            self.udp = default_udp;
263        }
264
265        if self.tcp_fast_open.is_none() {
266            self.tcp_fast_open = default_tfo;
267        }
268
269        if self.allow_insecure.is_none() {
270            self.allow_insecure = default_scv;
271        }
272
273        self
274    }
275}
276
277/// Default provider group names as constants.
278pub const SS_DEFAULT_GROUP: &str = "SSProvider";
279pub const SSR_DEFAULT_GROUP: &str = "SSRProvider";
280pub const V2RAY_DEFAULT_GROUP: &str = "V2RayProvider";
281pub const SOCKS_DEFAULT_GROUP: &str = "SocksProvider";
282pub const HTTP_DEFAULT_GROUP: &str = "HTTPProvider";
283pub const TROJAN_DEFAULT_GROUP: &str = "TrojanProvider";
284pub const SNELL_DEFAULT_GROUP: &str = "SnellProvider";
285pub const WG_DEFAULT_GROUP: &str = "WireGuardProvider";
286pub const HYSTERIA_DEFAULT_GROUP: &str = "HysteriaProvider";
287pub const HYSTERIA2_DEFAULT_GROUP: &str = "Hysteria2Provider";