Skip to main content

gooty_proxy/definitions/
enums.rs

1//! # Models for Gooty Proxy
2//!
3//! This module contains data structures and type definitions for the core components
4//! of the Gooty Proxy application.
5//!
6//! ## Main Components
7//!
8//! * **Proxies** - Representation of individual proxies with their connection details,
9//!   authentication, and metadata
10//! * **Proxy Sources** - Providers and services that supply proxy information
11//! * **Browsers** - Browser configurations and profiles for proxy usage
12//! * **Regex Patterns** - Regular expression patterns for validation, matching and filtering
13//! * **Connection** - Connection states, statistics, and health monitoring
14//! * **User Settings** - User configuration and preferences
15//!
16//! The structures defined here are used throughout the application for data persistence,
17//! configuration management, and service integration.
18//!
19
20use serde::{Deserialize, Serialize};
21use std::fmt;
22
23// Re-export the Proxy struct from the proxy module
24pub use super::proxy::Proxy;
25
26/// # Proxy Type
27///
28/// Represents the protocol used by a proxy server.
29///
30/// Different proxy types offer varying levels of functionality, security, and speed:
31/// - HTTP/HTTPS proxies only work with web traffic
32/// - SOCKS proxies can handle any TCP/UDP traffic
33/// - SOCKS5 adds authentication and IPv6 support over SOCKS4
34///
35/// ## Examples
36///
37/// ```
38/// use gooty_proxy::definitions::enums::ProxyType;
39/// use std::str::FromStr;
40///
41/// // Creating from string
42/// let proxy_type = ProxyType::from_str("http").unwrap();
43/// assert_eq!(proxy_type, ProxyType::Http);
44///
45/// // Converting to string
46/// assert_eq!(ProxyType::Socks5.to_string(), "SOCKS5");
47/// ```
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
49pub enum ProxyType {
50    /// HTTP proxy protocol - widely supported but unencrypted
51    Http,
52
53    /// HTTPS proxy protocol - encrypted connection to the proxy
54    Https,
55
56    /// SOCKS4 proxy protocol - supports TCP connections
57    Socks4,
58
59    /// SOCKS5 proxy protocol - supports TCP, UDP, and authentication
60    Socks5,
61}
62
63impl ProxyType {
64    /// Returns the default port for this proxy type
65    ///
66    /// # Returns
67    ///
68    /// The standard port number commonly used for this proxy type
69    ///
70    /// # Examples
71    ///
72    /// ```
73    /// use gooty_proxy::definitions::enums::ProxyType;
74    ///
75    /// assert_eq!(ProxyType::Http.default_port(), 8080);
76    /// assert_eq!(ProxyType::Socks5.default_port(), 1080);
77    /// ```
78    #[must_use]
79    pub fn default_port(&self) -> u16 {
80        match self {
81            ProxyType::Http => 8080,
82            ProxyType::Https => 8443,
83            ProxyType::Socks4 | ProxyType::Socks5 => 1080,
84        }
85    }
86}
87
88impl fmt::Display for ProxyType {
89    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90        match self {
91            ProxyType::Http => write!(f, "HTTP"),
92            ProxyType::Https => write!(f, "HTTPS"),
93            ProxyType::Socks4 => write!(f, "SOCKS4"),
94            ProxyType::Socks5 => write!(f, "SOCKS5"),
95        }
96    }
97}
98
99impl std::str::FromStr for ProxyType {
100    type Err = String;
101
102    /// Attempts to convert a string to a `ProxyType`
103    ///
104    /// # Arguments
105    ///
106    /// * `s` - The string to convert
107    ///
108    /// # Returns
109    ///
110    /// * `Ok(ProxyType)` - If the string matches a known proxy type
111    /// * `Err(String)` - If the string doesn't match any known proxy type
112    fn from_str(s: &str) -> Result<Self, Self::Err> {
113        match s.to_lowercase().as_str() {
114            "http" => Ok(ProxyType::Http),
115            "https" => Ok(ProxyType::Https),
116            "socks4" => Ok(ProxyType::Socks4),
117            "socks5" => Ok(ProxyType::Socks5),
118            _ => Err(format!("Unknown proxy type: {s}")),
119        }
120    }
121}
122
123/// Represents the anonymity level of a proxy.
124///
125/// This enum categorizes proxies based on how much information about the client
126/// they reveal to the target server.
127///
128/// # Variants
129///
130/// * `Transparent` - The proxy reveals the client's IP address in headers.
131/// * `Anonymous` - The proxy reveals it is a proxy but hides the client's IP.
132/// * `Elite` - The proxy does not reveal any proxy information or client IP.
133///
134/// # Examples
135///
136/// ```
137/// use gooty_proxy::definitions::enums::AnonymityLevel;
138///
139/// let level = AnonymityLevel::Elite;
140/// assert_eq!(level.to_string(), "Elite");
141/// ```
142#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
143pub enum AnonymityLevel {
144    /// Your real IP address is visible in headers (least anonymous)
145    Transparent,
146
147    /// Your real IP is hidden but the server knows you're using a proxy
148    Anonymous,
149
150    /// Neither your IP nor proxy usage is detectable (most anonymous)
151    Elite,
152}
153
154impl fmt::Display for AnonymityLevel {
155    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156        match self {
157            AnonymityLevel::Transparent => write!(f, "Transparent"),
158            AnonymityLevel::Anonymous => write!(f, "Anonymous"),
159            AnonymityLevel::Elite => write!(f, "Elite"),
160        }
161    }
162}
163
164impl std::str::FromStr for AnonymityLevel {
165    type Err = String;
166
167    /// Converts a string to an `AnonymityLevel`
168    ///
169    /// # Arguments
170    ///
171    /// * `s` - The string to convert
172    ///
173    /// # Returns
174    ///
175    /// * `Ok(AnonymityLevel)` - If the string matches a known anonymity level
176    /// * `Err(String)` - If the string doesn't match any known anonymity level
177    fn from_str(s: &str) -> Result<Self, Self::Err> {
178        match s.to_lowercase().as_str() {
179            "transparent" => Ok(AnonymityLevel::Transparent),
180            "anonymous" => Ok(AnonymityLevel::Anonymous),
181            "elite" | "high_anonymous" | "high anonymous" => Ok(AnonymityLevel::Elite),
182            _ => Err(format!("Unknown anonymity level: {s}")),
183        }
184    }
185}
186
187/// A comparison method to determine which anonymity level is better
188impl Ord for AnonymityLevel {
189    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
190        // Elite > Anonymous > Transparent
191        use std::cmp::Ordering;
192        match (self, other) {
193            // Equal cases
194            (AnonymityLevel::Elite, AnonymityLevel::Elite)
195            | (AnonymityLevel::Anonymous, AnonymityLevel::Anonymous)
196            | (AnonymityLevel::Transparent, AnonymityLevel::Transparent) => Ordering::Equal,
197
198            // Greater than cases
199            (AnonymityLevel::Elite, _)
200            | (AnonymityLevel::Anonymous, AnonymityLevel::Transparent) => Ordering::Greater,
201
202            // Less than cases
203            (AnonymityLevel::Transparent, _)
204            | (AnonymityLevel::Anonymous, AnonymityLevel::Elite) => Ordering::Less,
205        }
206    }
207}
208
209impl PartialOrd for AnonymityLevel {
210    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
211        Some(self.cmp(other))
212    }
213}
214
215/// Represents the state of a proxy validation check
216#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
217pub enum ValidationState {
218    /// Check has not yet started
219    Pending,
220
221    /// Check is currently being performed
222    InProgress,
223
224    /// Check completed successfully
225    Success,
226
227    /// Check failed
228    Failed,
229}
230
231impl fmt::Display for ValidationState {
232    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233        match self {
234            ValidationState::Pending => write!(f, "Pending"),
235            ValidationState::InProgress => write!(f, "In Progress"),
236            ValidationState::Success => write!(f, "Success"),
237            ValidationState::Failed => write!(f, "Failed"),
238        }
239    }
240}
241
242/// Represents the different rotation strategies for proxy selection
243#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
244pub enum RotationStrategy {
245    /// Round-robin selection without considering performance
246    Sequential,
247    /// Random selection without considering performance
248    Random,
249    /// Select based on lowest latency
250    Performance,
251    /// Select based on successful requests history
252    Reliability,
253    /// Weighted random selection based on performance metrics
254    Weighted,
255}
256
257impl fmt::Display for RotationStrategy {
258    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
259        match self {
260            RotationStrategy::Sequential => write!(f, "Sequential"),
261            RotationStrategy::Random => write!(f, "Random"),
262            RotationStrategy::Performance => write!(f, "Performance"),
263            RotationStrategy::Reliability => write!(f, "Reliability"),
264            RotationStrategy::Weighted => write!(f, "Weighted"),
265        }
266    }
267}
268
269/// Represents the status of a proxy source
270#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
271pub enum SourceStatus {
272    /// Source is active and being used
273    Active,
274    /// Source is temporarily disabled
275    Disabled,
276    /// Source has failed too many times and is blacklisted
277    Blacklisted,
278    /// Source is being used for the first time
279    New,
280}
281
282impl fmt::Display for SourceStatus {
283    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284        match self {
285            SourceStatus::Active => write!(f, "Active"),
286            SourceStatus::Disabled => write!(f, "Disabled"),
287            SourceStatus::Blacklisted => write!(f, "Blacklisted"),
288            SourceStatus::New => write!(f, "New"),
289        }
290    }
291}
292
293/// # Log Level
294///
295/// Represents the level of detail in logging throughout the application.
296///
297/// Log levels help filter the verbosity of log output, from the most
298/// critical-only messages (Error) to highly detailed debugging information (Trace).
299///
300/// ## Examples
301///
302/// ```
303/// use gooty_proxy::definitions::enums::LogLevel;
304/// use std::fmt;
305///
306/// // Display a log level as string
307/// assert_eq!(LogLevel::Info.to_string(), "INFO");
308///
309/// // Use in logging context
310/// let level = LogLevel::Debug;
311/// if level == LogLevel::Debug {
312///     println!("Debug information: {}", "details");
313/// }
314/// ```
315#[derive(clap::ValueEnum, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
316pub enum LogLevel {
317    /// Critical errors that may cause application failure
318    Error,
319    /// Issues that should be addressed but don't prevent operation
320    Warn,
321    /// General operational messages about system state
322    Info,
323    /// Detailed information for debugging purposes
324    Debug,
325    /// Extremely verbose information for tracing execution
326    Trace,
327}
328
329impl fmt::Display for LogLevel {
330    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331        match self {
332            LogLevel::Error => write!(f, "ERROR"),
333            LogLevel::Warn => write!(f, "WARN"),
334            LogLevel::Info => write!(f, "INFO"),
335            LogLevel::Debug => write!(f, "DEBUG"),
336            LogLevel::Trace => write!(f, "TRACE"),
337        }
338    }
339}
340
341/// Represents a verification method for proxy testing
342#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
343pub enum VerificationMethod {
344    /// Simple connectivity test
345    Connectivity,
346    /// Check if proxy can access specific target
347    TargetAccess,
348    /// Full anonymity check using judge services
349    AnonymityCheck,
350    /// Extended verification with multiple judges and targets
351    Comprehensive,
352}
353
354impl fmt::Display for VerificationMethod {
355    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
356        match self {
357            VerificationMethod::Connectivity => write!(f, "Connectivity"),
358            VerificationMethod::TargetAccess => write!(f, "Target Access"),
359            VerificationMethod::AnonymityCheck => write!(f, "Anonymity Check"),
360            VerificationMethod::Comprehensive => write!(f, "Comprehensive"),
361        }
362    }
363}
364
365/// # Judgement Mode
366///
367/// Represents different levels of proxy judgement/evaluation intensity.
368///
369/// * `None` - No judgement is performed
370/// * `Quick` - Basic, fast evaluation of proxies
371/// * `Full` - Comprehensive, detailed evaluation of proxies
372///
373/// ## Examples
374///
375/// ```
376/// use gooty_proxy::definitions::enums::JudgementMode;
377///
378/// let mode = JudgementMode::Quick;
379/// assert_eq!(mode as i32, 1);
380/// assert_eq!(mode.to_string(), "Quick");
381/// ```
382#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
383pub enum JudgementMode {
384    /// No judgement is performed
385    None = 0,
386    /// Basic, fast evaluation of proxies
387    Quick = 1,
388    /// Comprehensive, detailed evaluation of proxies
389    Full = 2,
390}
391
392impl fmt::Display for JudgementMode {
393    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
394        match self {
395            JudgementMode::None => write!(f, "None"),
396            JudgementMode::Quick => write!(f, "Quick"),
397            JudgementMode::Full => write!(f, "Full"),
398        }
399    }
400}
401
402impl std::str::FromStr for JudgementMode {
403    type Err = String;
404
405    /// Converts a string to a `JudgementMode`
406    ///
407    /// # Arguments
408    ///
409    /// * `s` - The string to convert
410    ///
411    /// # Returns
412    ///
413    /// * `Ok(JudgementMode)` - If the string matches a known judgement mode
414    /// * `Err(String)` - If the string doesn't match any known judgement mode
415    fn from_str(s: &str) -> Result<Self, Self::Err> {
416        match s.to_lowercase().as_str() {
417            "none" | "0" => Ok(JudgementMode::None),
418            "quick" | "1" => Ok(JudgementMode::Quick),
419            "full" | "2" => Ok(JudgementMode::Full),
420            _ => Err(format!("Unknown judgement mode: {s}")),
421        }
422    }
423}