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