whois_cli/
cli.rs

1use clap::Parser;
2
3#[derive(Parser)]
4#[command(
5    author = "Pysio",
6    version = env!("CARGO_PKG_VERSION"),
7    about = "A simple WHOIS query tool with advanced features"
8)]
9pub struct Cli {
10    /// Domain name or IP address to query
11    pub domain: String,
12
13    /// WHOIS server to use (bypasses IANA lookup)
14    #[arg(short, long)]
15    pub server: Option<String>,
16
17    /// Port number to use
18    #[arg(short, long, default_value_t = 43)]
19    pub port: u16,
20
21    /// Display verbose output
22    #[arg(short, long)]
23    pub verbose: bool,
24    
25    /// Query DN42 information from lantian.pub
26    #[arg(long = "42")]
27    pub dn42: bool,
28    
29    /// Query from bgp.tools
30    #[arg(long)]
31    pub bgptools: bool,
32    
33    /// Disable colored output
34    #[arg(long)]
35    pub no_color: bool,
36    
37    /// Easter egg: MTF flag colors (hidden option)
38    #[arg(long, hide = true)]
39    pub mtf: bool,
40
41    /// Disable hyperlinks in terminal output (hyperlinks are enabled by default)
42    #[arg(long, help = "Disable clickable hyperlinks for RIR database results")]
43    pub no_hyperlinks: bool,
44
45    /// Disable server-side coloring protocol (server-side rendering is default)
46    #[arg(long, help = "Disable server-side coloring and use client-side only")]
47    pub no_server_color: bool,
48
49    /// Enable Markdown formatting from server
50    #[arg(long, help = "Request Markdown-formatted output from server")]
51    pub markdown: bool,
52
53    /// Enable image display in terminal
54    #[arg(long, help = "Enable inline image display in terminal")]
55    pub images: bool,
56}
57
58impl Cli {
59    /// Check if colored output should be used
60    pub fn use_color(&self) -> bool {
61        !self.no_color
62    }
63
64    /// Check if MTF colors should be used
65    pub fn use_mtf_colors(&self) -> bool {
66        self.mtf
67    }
68
69    /// Check if DN42 mode should be used
70    pub fn use_dn42(&self) -> bool {
71        self.dn42 || self.domain.to_uppercase().starts_with("AS42424")
72    }
73
74    /// Check if BGP tools mode should be used
75    pub fn use_bgptools(&self) -> bool {
76        self.bgptools
77    }
78
79    /// Check if hyperlinks should be used
80    pub fn use_hyperlinks(&self) -> bool {
81        !self.no_hyperlinks
82    }
83
84    /// Check if server-side coloring should be used (default: true)
85    pub fn use_server_color(&self) -> bool {
86        !self.no_server_color
87    }
88
89    /// Check if Markdown formatting should be requested
90    pub fn use_markdown(&self) -> bool {
91        self.markdown
92    }
93
94    /// Check if image display should be enabled
95    pub fn use_images(&self) -> bool {
96        self.images
97    }
98}
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103
104    fn create_test_cli(domain: &str) -> Cli {
105        Cli {
106            domain: domain.to_string(),
107            server: None,
108            port: 43,
109            verbose: false,
110            dn42: false,
111            bgptools: false,
112            no_color: false,
113            mtf: false,
114            no_hyperlinks: false,
115            no_server_color: false,
116            markdown: false,
117            images: false,
118        }
119    }
120
121    #[test]
122    fn test_use_color_default() {
123        let cli = create_test_cli("example.com");
124        assert!(cli.use_color());
125    }
126
127    #[test]
128    fn test_use_color_disabled() {
129        let mut cli = create_test_cli("example.com");
130        cli.no_color = true;
131        assert!(!cli.use_color());
132    }
133
134    #[test]
135    fn test_use_mtf_colors() {
136        let mut cli = create_test_cli("example.com");
137        assert!(!cli.use_mtf_colors());
138        
139        cli.mtf = true;
140        assert!(cli.use_mtf_colors());
141    }
142
143    #[test]
144    fn test_use_dn42_explicit_flag() {
145        let mut cli = create_test_cli("example.com");
146        assert!(!cli.use_dn42());
147        
148        cli.dn42 = true;
149        assert!(cli.use_dn42());
150    }
151
152    #[test]
153    fn test_use_dn42_auto_detection() {
154        let cli = create_test_cli("AS4242420000");
155        assert!(cli.use_dn42());
156        
157        let cli = create_test_cli("as4242420000");
158        assert!(cli.use_dn42());
159        
160        let cli = create_test_cli("AS4242421234");
161        assert!(cli.use_dn42());
162    }
163
164    #[test]
165    fn test_use_dn42_not_triggered() {
166        let cli = create_test_cli("AS15169");
167        assert!(!cli.use_dn42());
168        
169        let cli = create_test_cli("example.com");
170        assert!(!cli.use_dn42());
171    }
172
173    #[test]
174    fn test_use_bgptools() {
175        let mut cli = create_test_cli("AS15169");
176        assert!(!cli.use_bgptools());
177        
178        cli.bgptools = true;
179        assert!(cli.use_bgptools());
180    }
181
182    #[test]
183    fn test_use_hyperlinks_default() {
184        let cli = create_test_cli("example.com");
185        assert!(cli.use_hyperlinks());
186    }
187
188    #[test]
189    fn test_use_hyperlinks_disabled() {
190        let mut cli = create_test_cli("example.com");
191        cli.no_hyperlinks = true;
192        assert!(!cli.use_hyperlinks());
193    }
194
195    #[test]
196    fn test_port_default() {
197        let cli = create_test_cli("example.com");
198        assert_eq!(cli.port, 43);
199    }
200
201    #[test]
202    fn test_domain_assignment() {
203        let cli = create_test_cli("test.example.com");
204        assert_eq!(cli.domain, "test.example.com");
205    }
206
207    #[test]
208    fn test_use_server_color() {
209        let mut cli = create_test_cli("example.com");
210        assert!(cli.use_server_color()); // Default is true
211        
212        cli.no_server_color = true;
213        assert!(!cli.use_server_color());
214    }
215
216    #[test]
217    fn test_use_markdown() {
218        let mut cli = create_test_cli("example.com");
219        assert!(!cli.use_markdown()); // Default is false
220        
221        cli.markdown = true;
222        assert!(cli.use_markdown());
223    }
224
225    #[test]
226    fn test_use_images() {
227        let mut cli = create_test_cli("example.com");
228        assert!(!cli.use_images()); // Default is false
229        
230        cli.images = true;
231        assert!(cli.use_images());
232    }
233
234    #[test]
235    fn test_all_flags_together() {
236        let mut cli = create_test_cli("AS4242420000");
237        cli.dn42 = true;
238        cli.bgptools = true;
239        cli.no_color = true;
240        cli.mtf = true;
241        cli.no_hyperlinks = true;
242        cli.verbose = true;
243        cli.no_server_color = true;
244        cli.markdown = true;
245        cli.images = true;
246        
247        // DN42 should be true due to both flag and auto-detection
248        assert!(cli.use_dn42());
249        assert!(cli.use_bgptools());
250        assert!(!cli.use_color());
251        assert!(cli.use_mtf_colors());
252        assert!(!cli.use_hyperlinks());
253        assert!(!cli.use_server_color());
254        assert!(cli.use_markdown());
255        assert!(cli.use_images());
256        assert!(cli.verbose);
257    }
258}