Spawn a command, wait for it with a timeout, and return the result. Stdout is suppressed. Stderr is captured for error reporting.
(
command: &mut Command,
timeout: Duration,
)
| 511 | /// |
| 512 | /// Stdout is suppressed. Stderr is captured for error reporting. |
| 513 | fn run_command_with_timeout( |
| 514 | command: &mut Command, |
| 515 | timeout: Duration, |
| 516 | ) -> Result<CommandResult, String> { |
| 517 | let mut child = command |
| 518 | .stdout(Stdio::null()) |
| 519 | .stderr(Stdio::piped()) |
| 520 | .spawn() |
| 521 | .map_err(|e| format!("Failed to spawn formatter: {}", e))?; |
| 522 | |
| 523 | let start = std::time::Instant::now(); |
| 524 | loop { |
| 525 | match child.try_wait() { |
| 526 | Ok(Some(status)) => { |
| 527 | let stderr = child |
| 528 | .stderr |
| 529 | .take() |
| 530 | .and_then(|mut s| { |
| 531 | let mut buf = String::new(); |
| 532 | std::io::Read::read_to_string(&mut s, &mut buf).ok()?; |
| 533 | Some(buf) |
| 534 | }) |
| 535 | .unwrap_or_default(); |
| 536 | |
| 537 | return Ok(CommandResult { |
| 538 | code: status.code().unwrap_or(-1), |
| 539 | stderr, |
| 540 | }); |
| 541 | } |
| 542 | Ok(None) => { |
| 543 | if start.elapsed() >= timeout { |
| 544 | let _ = child.kill(); |
| 545 | let _ = child.wait(); |
| 546 | return Err(format!( |
| 547 | "Formatter timed out after {}ms", |
| 548 | timeout.as_millis() |
| 549 | )); |
| 550 | } |
| 551 | std::thread::sleep(Duration::from_millis(50)); |
| 552 | } |
| 553 | Err(e) => { |
| 554 | let _ = child.kill(); |
| 555 | return Err(format!("Error waiting for formatter: {}", e)); |
| 556 | } |
| 557 | } |
| 558 | } |
| 559 | } |
| 560 | |
| 561 | /// Compute the `TextEdit`s needed to transform `original` into `formatted`. |
| 562 | /// |
no test coverage detected