libsubconverter/models/
proxy_group_config.rs1#[derive(Debug, Clone, PartialEq, Eq)]
3pub enum ProxyGroupType {
4 Select,
5 URLTest,
6 Fallback,
7 LoadBalance,
8 Relay,
9 SSID,
10 Smart,
11}
12
13impl ProxyGroupType {
14 pub fn as_str(&self) -> &'static str {
16 match self {
17 ProxyGroupType::Select => "select",
18 ProxyGroupType::URLTest => "url-test",
19 ProxyGroupType::LoadBalance => "load-balance",
20 ProxyGroupType::Fallback => "fallback",
21 ProxyGroupType::Relay => "relay",
22 ProxyGroupType::SSID => "ssid",
23 ProxyGroupType::Smart => "smart",
24 }
25 }
26}
27
28#[derive(Debug, Clone, PartialEq, Eq)]
30pub enum BalanceStrategy {
31 ConsistentHashing,
32 RoundRobin,
33}
34
35impl BalanceStrategy {
36 pub fn as_str(&self) -> &'static str {
38 match self {
39 BalanceStrategy::ConsistentHashing => "consistent-hashing",
40 BalanceStrategy::RoundRobin => "round-robin",
41 }
42 }
43}
44
45#[derive(Debug, Clone)]
47pub struct ProxyGroupConfig {
48 pub name: String,
50 pub group_type: ProxyGroupType,
52 pub proxies: Vec<String>,
54 pub using_provider: Vec<String>,
56 pub url: String,
58 pub interval: u32,
60 pub timeout: u32,
62 pub tolerance: u32,
64 pub strategy: BalanceStrategy,
66 pub lazy: bool,
68 pub disable_udp: bool,
70 pub persistent: bool,
72 pub evaluate_before_use: bool,
74}
75
76impl Default for ProxyGroupConfig {
77 fn default() -> Self {
78 Self {
79 name: String::new(),
80 group_type: ProxyGroupType::Select,
81 proxies: Vec::new(),
82 using_provider: Vec::new(),
83 url: String::new(),
84 interval: 0,
85 timeout: 0,
86 tolerance: 0,
87 strategy: BalanceStrategy::ConsistentHashing,
88 lazy: false,
89 disable_udp: false,
90 persistent: false,
91 evaluate_before_use: false,
92 }
93 }
94}
95
96impl ProxyGroupConfig {
97 pub fn new(name: String, group_type: ProxyGroupType) -> Self {
99 Self {
100 name,
101 group_type,
102 ..Default::default()
103 }
104 }
105
106 pub fn type_str(&self) -> &'static str {
108 self.group_type.as_str()
109 }
110
111 pub fn strategy_str(&self) -> &'static str {
113 self.strategy.as_str()
114 }
115}
116
117pub type ProxyGroupConfigs = Vec<ProxyGroupConfig>;
119
120use serde::ser::SerializeStruct;
121use serde::{Serialize, Serializer};
122
123impl Serialize for ProxyGroupConfig {
124 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
125 where
126 S: Serializer,
127 {
128 let mut field_count = 2; match self.group_type {
133 ProxyGroupType::LoadBalance => {
134 field_count += 4; if !self.lazy {
136 field_count += 1; }
138 }
139 ProxyGroupType::URLTest | ProxyGroupType::Smart => {
140 field_count += 2; if !self.lazy {
142 field_count += 1; }
144 if self.tolerance > 0 {
145 field_count += 1; }
147 }
148 ProxyGroupType::Fallback => {
149 field_count += 2; if self.tolerance > 0 {
151 field_count += 1; }
153 }
154 _ => {}
155 }
156
157 if self.disable_udp {
159 field_count += 1;
160 }
161 if self.persistent {
162 field_count += 1;
163 }
164 if self.evaluate_before_use {
165 field_count += 1;
166 }
167
168 if !self.proxies.is_empty() {
170 field_count += 1;
171 }
172 if !self.using_provider.is_empty() {
173 field_count += 1;
174 }
175
176 let mut state = serializer.serialize_struct("ProxyGroup", field_count)?;
178
179 state.serialize_field("name", &self.name)?;
181
182 let type_str = if self.group_type == ProxyGroupType::Smart {
184 "url-test"
185 } else {
186 self.type_str()
187 };
188 state.serialize_field("type", &type_str)?;
189
190 match self.group_type {
192 ProxyGroupType::LoadBalance => {
193 state.serialize_field("strategy", &self.strategy_str())?;
195 if !self.lazy {
196 state.serialize_field("lazy", &self.lazy)?;
197 }
198 state.serialize_field("url", &self.url)?;
199 if self.interval > 0 {
200 state.serialize_field("interval", &self.interval)?;
201 }
202 if self.tolerance > 0 {
203 state.serialize_field("tolerance", &self.tolerance)?;
204 }
205 }
206 ProxyGroupType::URLTest | ProxyGroupType::Smart => {
207 if !self.lazy {
209 state.serialize_field("lazy", &self.lazy)?;
210 }
211 state.serialize_field("url", &self.url)?;
212 if self.interval > 0 {
213 state.serialize_field("interval", &self.interval)?;
214 }
215 if self.tolerance > 0 {
216 state.serialize_field("tolerance", &self.tolerance)?;
217 }
218 }
219 ProxyGroupType::Fallback => {
220 state.serialize_field("url", &self.url)?;
222 if self.interval > 0 {
223 state.serialize_field("interval", &self.interval)?;
224 }
225 if self.tolerance > 0 {
226 state.serialize_field("tolerance", &self.tolerance)?;
227 }
228 }
229 _ => {}
230 }
231
232 if self.disable_udp {
234 state.serialize_field("disable-udp", &self.disable_udp)?;
235 }
236 if self.persistent {
237 state.serialize_field("persistent", &self.persistent)?;
238 }
239 if self.evaluate_before_use {
240 state.serialize_field("evaluate-before-use", &self.evaluate_before_use)?;
241 }
242
243 if !self.proxies.is_empty() {
245 state.serialize_field("proxies", &self.proxies)?;
246 }
247
248 if !self.using_provider.is_empty() {
250 state.serialize_field("use", &self.using_provider)?;
251 }
252
253 state.end()
254 }
255}