eggress_pproxy_compat/
gate.rs1use crate::args::PproxyArgs;
11use crate::warnings::{CompatWarning, TranslationOutput, UnsupportedFeature};
12
13#[derive(Debug, Clone, PartialEq)]
15pub enum BlockReason {
16 UnknownFlag(String),
18 Unsupported(UnsupportedFeature),
20}
21
22#[derive(Debug, Clone, PartialEq)]
24pub struct ExecutionGate {
25 pub blockers: Vec<BlockReason>,
27 pub warnings: Vec<CompatWarning>,
29}
30
31impl ExecutionGate {
32 pub fn allows_start(&self) -> bool {
34 self.blockers.is_empty()
35 }
36
37 pub fn blocker_summary(&self) -> String {
39 self.blockers
40 .iter()
41 .map(|b| match b {
42 BlockReason::UnknownFlag(f) => format!("unknown option '{f}'"),
43 BlockReason::Unsupported(u) => format!("{u}"),
44 })
45 .collect::<Vec<_>>()
46 .join("\n")
47 }
48}
49
50pub fn evaluate(args: &PproxyArgs, output: &TranslationOutput) -> ExecutionGate {
57 let mut blockers: Vec<BlockReason> = Vec::new();
58 for flag in args.strict_parser_violations() {
59 blockers.push(BlockReason::UnknownFlag(flag.clone()));
60 }
61 for u in &output.unsupported {
62 blockers.push(BlockReason::Unsupported(u.clone()));
63 }
64 ExecutionGate {
65 blockers,
66 warnings: output.warnings.clone(),
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use crate::args::PproxyArgs;
74
75 fn parse(args: &[&str]) -> PproxyArgs {
76 let raw: Vec<String> = args.iter().map(|s| s.to_string()).collect();
77 PproxyArgs::parse(&raw).expect("parser failed")
78 }
79
80 #[test]
81 fn evaluate_allows_clean_translation() {
82 let args = parse(&["-l", "http://:8080", "-r", "socks5://proxy:1080"]);
83 let output = crate::translate::translate_pproxy_args(&args).unwrap();
84 let gate = evaluate(&args, &output);
85 assert!(gate.allows_start(), "unexpected blockers: {:?}", gate);
86 assert!(gate.warnings.is_empty());
87 }
88
89 #[test]
90 fn evaluate_blocks_unknown_flag() {
91 let args = parse(&["-l", "http://:8080", "--bogus-flag"]);
92 let output = crate::translate::translate_pproxy_args(&args).unwrap();
93 let gate = evaluate(&args, &output);
94 assert!(!gate.allows_start());
95 assert!(matches!(
96 gate.blockers.first(),
97 Some(BlockReason::UnknownFlag(f)) if f == "--bogus-flag"
98 ));
99 }
100
101 #[test]
102 fn evaluate_blocks_daemon() {
103 let args = parse(&["-l", "http://:8080", "--daemon"]);
104 let output = crate::translate::translate_pproxy_args(&args).unwrap();
105 let gate = evaluate(&args, &output);
106 #[cfg(feature = "daemon")]
107 assert!(gate.allows_start());
108 #[cfg(not(feature = "daemon"))]
109 {
110 assert!(!gate.allows_start());
111 assert!(gate
112 .blockers
113 .iter()
114 .any(|b| matches!(b, BlockReason::Unsupported(u) if u.feature == "daemon")));
115 }
116 }
117
118 #[test]
119 fn evaluate_allows_sys_with_warning() {
120 let args = parse(&["-l", "http://:8080", "--sys"]);
121 let output = crate::translate::translate_pproxy_args(&args).unwrap();
122 let gate = evaluate(&args, &output);
123 assert!(gate.allows_start(), "unexpected blockers: {:?}", gate);
124 }
125
126 #[test]
127 fn evaluate_allows_auth_with_warning() {
128 let args = parse(&["-l", "http://:8080", "--auth", "3600"]);
129 let output = crate::translate::translate_pproxy_args(&args).unwrap();
130 let gate = evaluate(&args, &output);
131 assert!(gate.allows_start(), "unexpected blockers: {:?}", gate);
132 }
133
134 #[test]
135 fn evaluate_blocks_malformed_auth() {
136 let raw = vec![
137 "-l".to_string(),
138 "http://:8080".to_string(),
139 "--auth".to_string(),
140 "abc".to_string(),
141 ];
142 let err = PproxyArgs::parse(&raw).unwrap_err();
143 let _ = err;
146 }
147
148 #[test]
149 fn evaluate_does_not_block_d_flag() {
150 let args = parse(&["-l", "http://:8080", "-d"]);
151 let output = crate::translate::translate_pproxy_args(&args).unwrap();
152 let gate = evaluate(&args, &output);
153 assert!(gate.allows_start(), "unexpected blockers: {:?}", gate);
154 }
155
156 #[test]
157 fn evaluate_blocker_summary_lists_each_reason() {
158 let args = parse(&["-l", "http://:8080", "--bogus-flag", "--daemon"]);
159 let output = crate::translate::translate_pproxy_args(&args).unwrap();
160 let gate = evaluate(&args, &output);
161 let summary = gate.blocker_summary();
162 assert!(summary.contains("--bogus-flag"));
163 #[cfg(not(feature = "daemon"))]
164 assert!(summary.contains("daemon"));
165 }
166}