Testing a small http-client on Linux using no_std & embedded reqwless.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Move validate task feature semantics toward feature-owned defaults

Refs: reqwl-backend-feature-matrix
Refs: reqwl-dns-mode-features

rektide ce29c374 4dbdf02b

+158 -76
.beads/dolt-monitor.pid.lock

This is a binary file and will not be displayed.

+158 -76
xtask/src/validate.rs
··· 15 15 } 16 16 17 17 impl BackendFeature { 18 - const fn feature(self) -> &'static str { 18 + const fn feature_flag(self) -> &'static str { 19 19 match self { 20 20 Self::PosixLibc => "backend-posix-libc", 21 21 Self::Rustix => "backend-rustix", 22 22 } 23 23 } 24 + 25 + const fn default_dns(self) -> DnsFeature { 26 + let _ = self; 27 + DnsFeature::GetAddrInfo 28 + } 29 + 30 + fn with_dns(self, dns: DnsFeature) -> FeatureSelection { 31 + TaskFeatures::none() 32 + .with_backend(self) 33 + .with_dns(dns) 34 + .selection() 35 + } 24 36 } 25 37 26 38 #[derive(Clone, Copy)] ··· 30 42 } 31 43 32 44 impl DnsFeature { 33 - const fn feature(self) -> &'static str { 45 + const fn feature_flag(self) -> &'static str { 34 46 match self { 35 47 Self::GetAddrInfo => "dns-getaddrinfo", 36 48 Self::IpOnly => "dns-ip-only", 37 49 } 38 50 } 51 + 52 + const fn default_backend(self) -> BackendFeature { 53 + let _ = self; 54 + BackendFeature::PosixLibc 55 + } 56 + 57 + const fn reject_message(self) -> Option<&'static str> { 58 + match self { 59 + Self::IpOnly => Some(DNS_IP_ONLY_REJECT_NEEDLE), 60 + Self::GetAddrInfo => None, 61 + } 62 + } 63 + } 64 + 65 + trait FeatureCommandArgs: Copy { 66 + fn check_display(self) -> String; 67 + fn check_args(self) -> Vec<String>; 68 + fn run_display(self, url: &str) -> String; 69 + fn run_args(self, url: &str) -> Vec<String>; 70 + } 71 + 72 + impl FeatureCommandArgs for BackendFeature { 73 + fn check_display(self) -> String { 74 + TaskFeatures::none() 75 + .with_backend(self) 76 + .selection() 77 + .check_display() 78 + } 79 + 80 + fn check_args(self) -> Vec<String> { 81 + TaskFeatures::none() 82 + .with_backend(self) 83 + .selection() 84 + .check_args() 85 + } 86 + 87 + fn run_display(self, url: &str) -> String { 88 + TaskFeatures::none() 89 + .with_backend(self) 90 + .selection() 91 + .run_display(url) 92 + } 93 + 94 + fn run_args(self, url: &str) -> Vec<String> { 95 + TaskFeatures::none() 96 + .with_backend(self) 97 + .selection() 98 + .run_args(url) 99 + } 100 + } 101 + 102 + impl FeatureCommandArgs for DnsFeature { 103 + fn check_display(self) -> String { 104 + TaskFeatures::none() 105 + .with_dns(self) 106 + .selection() 107 + .check_display() 108 + } 109 + 110 + fn check_args(self) -> Vec<String> { 111 + TaskFeatures::none().with_dns(self).selection().check_args() 112 + } 113 + 114 + fn run_display(self, url: &str) -> String { 115 + TaskFeatures::none() 116 + .with_dns(self) 117 + .selection() 118 + .run_display(url) 119 + } 120 + 121 + fn run_args(self, url: &str) -> Vec<String> { 122 + TaskFeatures::none() 123 + .with_dns(self) 124 + .selection() 125 + .run_args(url) 126 + } 39 127 } 40 128 41 129 #[derive(Clone, Copy)] 42 - struct FeatureSelection { 130 + struct TaskFeatures { 43 131 backend: Option<BackendFeature>, 44 132 dns: Option<DnsFeature>, 45 133 extra_features: &'static [&'static str], 46 - no_default_features: bool, 47 134 } 48 135 49 - impl FeatureSelection { 136 + impl TaskFeatures { 50 137 const fn none() -> Self { 51 138 Self { 52 139 backend: None, 53 140 dns: None, 54 141 extra_features: EMPTY_FEATURES, 55 - no_default_features: false, 56 142 } 57 143 } 58 144 ··· 61 147 backend: Some(backend), 62 148 dns: self.dns, 63 149 extra_features: self.extra_features, 64 - no_default_features: true, 65 150 } 66 151 } 67 152 ··· 70 155 backend: self.backend, 71 156 dns: Some(dns), 72 157 extra_features: self.extra_features, 73 - no_default_features: true, 74 158 } 75 159 } 76 160 ··· 79 163 backend: self.backend, 80 164 dns: self.dns, 81 165 extra_features, 82 - no_default_features: self.no_default_features, 83 166 } 84 167 } 85 168 169 + fn selection(self) -> FeatureSelection { 170 + let backend = self 171 + .backend 172 + .or_else(|| self.dns.map(DnsFeature::default_backend)); 173 + let dns = self 174 + .dns 175 + .or_else(|| self.backend.map(BackendFeature::default_dns)); 176 + 177 + let no_default_features = backend.is_some() || dns.is_some(); 178 + 179 + FeatureSelection { 180 + backend, 181 + dns, 182 + extra_features: self.extra_features, 183 + no_default_features, 184 + } 185 + } 186 + } 187 + 188 + #[derive(Clone, Copy)] 189 + struct FeatureSelection { 190 + backend: Option<BackendFeature>, 191 + dns: Option<DnsFeature>, 192 + extra_features: &'static [&'static str], 193 + no_default_features: bool, 194 + } 195 + 196 + impl FeatureSelection { 86 197 fn feature_arg(self) -> Option<String> { 87 198 let mut features = Vec::new(); 88 199 if let Some(backend) = self.backend { 89 - features.push(backend.feature()); 200 + features.push(backend.feature_flag()); 90 201 } 91 202 if let Some(dns) = self.dns { 92 - features.push(dns.feature()); 203 + features.push(dns.feature_flag()); 93 204 } 94 205 features.extend(self.extra_features.iter().copied()); 95 206 ··· 148 259 } 149 260 } 150 261 151 - trait FeatureCommand: Copy { 152 - fn default_selection(self) -> FeatureSelection; 153 - 154 - fn check_display(self) -> String { 155 - self.default_selection().check_display() 156 - } 157 - 158 - fn check_args(self) -> Vec<String> { 159 - self.default_selection().check_args() 160 - } 161 - 162 - fn run_display(self, url: &str) -> String { 163 - self.default_selection().run_display(url) 164 - } 165 - 166 - fn run_args(self, url: &str) -> Vec<String> { 167 - self.default_selection().run_args(url) 168 - } 169 - } 170 - 171 - impl FeatureCommand for BackendFeature { 172 - fn default_selection(self) -> FeatureSelection { 173 - FeatureSelection::none() 174 - .with_backend(self) 175 - .with_dns(DnsFeature::GetAddrInfo) 176 - } 177 - } 178 - 179 - impl FeatureCommand for DnsFeature { 180 - fn default_selection(self) -> FeatureSelection { 181 - FeatureSelection::none() 182 - .with_backend(BackendFeature::PosixLibc) 183 - .with_dns(self) 184 - } 185 - } 186 - 187 262 #[derive(Clone, Copy, clap::ValueEnum)] 188 263 pub enum ValidateTask { 189 264 #[value(help = "run complete validation suite (build + runtime + guarded failure checks)")] ··· 213 288 } 214 289 215 290 impl ValidateTask { 216 - fn selection(self) -> Option<FeatureSelection> { 291 + fn features(self) -> Option<TaskFeatures> { 217 292 match self { 218 - Self::Check => Some(FeatureSelection::none()), 219 - Self::CheckHttps => Some(FeatureSelection::none().with_extras(HTTPS_FEATURES)), 220 - Self::CheckIpOnly => Some(DnsFeature::IpOnly.default_selection()), 221 - Self::RunHttpExample => Some(FeatureSelection::none()), 222 - Self::RunIpOnlyReject => Some(DnsFeature::IpOnly.default_selection()), 223 - Self::CheckRustix => Some(BackendFeature::Rustix.default_selection()), 293 + Self::Check => Some(TaskFeatures::none()), 294 + Self::CheckHttps => Some(TaskFeatures::none().with_extras(HTTPS_FEATURES)), 295 + Self::CheckIpOnly => Some(TaskFeatures::none().with_dns(DnsFeature::IpOnly)), 296 + Self::RunHttpExample => Some(TaskFeatures::none()), 297 + Self::RunIpOnlyReject => Some(TaskFeatures::none().with_dns(DnsFeature::IpOnly)), 298 + Self::CheckRustix => Some(TaskFeatures::none().with_backend(BackendFeature::Rustix)), 224 299 Self::CheckRustixIpOnly => Some( 225 - FeatureSelection::none() 300 + TaskFeatures::none() 226 301 .with_backend(BackendFeature::Rustix) 227 302 .with_dns(DnsFeature::IpOnly), 228 303 ), 229 - Self::RunRustixHttpExample => Some(BackendFeature::Rustix.default_selection()), 304 + Self::RunRustixHttpExample => { 305 + Some(TaskFeatures::none().with_backend(BackendFeature::Rustix)) 306 + } 230 307 Self::RunRustixIpOnlyReject => Some( 231 - FeatureSelection::none() 308 + TaskFeatures::none() 232 309 .with_backend(BackendFeature::Rustix) 233 310 .with_dns(DnsFeature::IpOnly), 234 311 ), ··· 280 357 ValidateTask::RunRustixHttpExample => { 281 358 run_run_backend_task(BackendFeature::Rustix, HTTP_EXAMPLE_URL) 282 359 } 283 - ValidateTask::RunRustixIpOnlyReject => run_ip_only_reject_task(task), 360 + ValidateTask::RunRustixIpOnlyReject => run_ip_only_reject_selection( 361 + BackendFeature::Rustix.with_dns(DnsFeature::IpOnly), 362 + DnsFeature::IpOnly, 363 + ), 284 364 } 285 365 } 286 366 287 367 fn run_check_task(task: ValidateTask) -> Result<(), String> { 288 368 let selection = task 289 - .selection() 290 - .ok_or_else(|| "task has no feature selection".to_owned())?; 369 + .features() 370 + .ok_or_else(|| "task has no feature selection".to_owned())? 371 + .selection(); 291 372 run_success(&selection.check_display(), &selection.check_args()) 292 373 } 293 374 294 375 fn run_run_task(task: ValidateTask, url: &str) -> Result<(), String> { 295 376 let selection = task 296 - .selection() 297 - .ok_or_else(|| "task has no feature selection".to_owned())?; 377 + .features() 378 + .ok_or_else(|| "task has no feature selection".to_owned())? 379 + .selection(); 298 380 run_success(&selection.run_display(url), &selection.run_args(url)) 299 - } 300 - 301 - fn run_ip_only_reject_task(task: ValidateTask) -> Result<(), String> { 302 - let selection = task 303 - .selection() 304 - .ok_or_else(|| "task has no feature selection".to_owned())?; 305 - run_expected_failure( 306 - &selection.run_display(HTTP_EXAMPLE_URL), 307 - &selection.run_args(HTTP_EXAMPLE_URL), 308 - DNS_IP_ONLY_REJECT_NEEDLE, 309 - ) 310 381 } 311 382 312 383 fn run_check_backend_task(backend: BackendFeature) -> Result<(), String> { ··· 322 393 } 323 394 324 395 fn run_ip_only_reject_dns_task(dns: DnsFeature) -> Result<(), String> { 396 + let selection = TaskFeatures::none().with_dns(dns).selection(); 397 + run_ip_only_reject_selection(selection, dns) 398 + } 399 + 400 + fn run_ip_only_reject_selection( 401 + selection: FeatureSelection, 402 + dns: DnsFeature, 403 + ) -> Result<(), String> { 404 + let needle = dns 405 + .reject_message() 406 + .ok_or_else(|| "dns feature has no reject expectation".to_owned())?; 325 407 run_expected_failure( 326 - &dns.run_display(HTTP_EXAMPLE_URL), 327 - &dns.run_args(HTTP_EXAMPLE_URL), 328 - DNS_IP_ONLY_REJECT_NEEDLE, 408 + &selection.run_display(HTTP_EXAMPLE_URL), 409 + &selection.run_args(HTTP_EXAMPLE_URL), 410 + needle, 329 411 ) 330 412 } 331 413