mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-27 22:04:17 +00:00
internal: Bring back JodChild into flychecking for cancellation
This commit is contained in:
parent
7db73875ac
commit
6438ef9aa3
4 changed files with 117 additions and 64 deletions
|
@ -5,54 +5,66 @@
|
|||
|
||||
use std::{
|
||||
io,
|
||||
process::{Command, Output, Stdio},
|
||||
process::{ChildStderr, ChildStdout, Command, Output, Stdio},
|
||||
};
|
||||
|
||||
use crate::JodChild;
|
||||
|
||||
pub fn streaming_output(
|
||||
out: ChildStdout,
|
||||
err: ChildStderr,
|
||||
on_stdout_line: &mut dyn FnMut(&str),
|
||||
on_stderr_line: &mut dyn FnMut(&str),
|
||||
) -> io::Result<(Vec<u8>, Vec<u8>)> {
|
||||
let mut stdout = Vec::new();
|
||||
let mut stderr = Vec::new();
|
||||
|
||||
imp::read2(out, err, &mut |is_out, data, eof| {
|
||||
let idx = if eof {
|
||||
data.len()
|
||||
} else {
|
||||
match data.iter().rposition(|b| *b == b'\n') {
|
||||
Some(i) => i + 1,
|
||||
None => return,
|
||||
}
|
||||
};
|
||||
{
|
||||
// scope for new_lines
|
||||
let new_lines = {
|
||||
let dst = if is_out { &mut stdout } else { &mut stderr };
|
||||
let start = dst.len();
|
||||
let data = data.drain(..idx);
|
||||
dst.extend(data);
|
||||
&dst[start..]
|
||||
};
|
||||
for line in String::from_utf8_lossy(new_lines).lines() {
|
||||
if is_out {
|
||||
on_stdout_line(line);
|
||||
} else {
|
||||
on_stderr_line(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
})?;
|
||||
|
||||
Ok((stdout, stderr))
|
||||
}
|
||||
|
||||
pub fn spawn_with_streaming_output(
|
||||
mut cmd: Command,
|
||||
on_stdout_line: &mut dyn FnMut(&str),
|
||||
on_stderr_line: &mut dyn FnMut(&str),
|
||||
) -> io::Result<Output> {
|
||||
let mut stdout = Vec::new();
|
||||
let mut stderr = Vec::new();
|
||||
|
||||
let cmd = cmd.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null());
|
||||
|
||||
let status = {
|
||||
let mut child = cmd.spawn()?;
|
||||
let out = child.stdout.take().unwrap();
|
||||
let err = child.stderr.take().unwrap();
|
||||
imp::read2(out, err, &mut |is_out, data, eof| {
|
||||
let idx = if eof {
|
||||
data.len()
|
||||
} else {
|
||||
match data.iter().rposition(|b| *b == b'\n') {
|
||||
Some(i) => i + 1,
|
||||
None => return,
|
||||
}
|
||||
};
|
||||
{
|
||||
// scope for new_lines
|
||||
let new_lines = {
|
||||
let dst = if is_out { &mut stdout } else { &mut stderr };
|
||||
let start = dst.len();
|
||||
let data = data.drain(..idx);
|
||||
dst.extend(data);
|
||||
&dst[start..]
|
||||
};
|
||||
for line in String::from_utf8_lossy(new_lines).lines() {
|
||||
if is_out {
|
||||
on_stdout_line(line);
|
||||
} else {
|
||||
on_stderr_line(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
})?;
|
||||
let _ = child.kill();
|
||||
child.wait()?
|
||||
};
|
||||
|
||||
let mut child = JodChild(cmd.spawn()?);
|
||||
let (stdout, stderr) = streaming_output(
|
||||
child.stdout.take().unwrap(),
|
||||
child.stderr.take().unwrap(),
|
||||
on_stdout_line,
|
||||
on_stderr_line,
|
||||
)?;
|
||||
let status = child.wait()?;
|
||||
Ok(Output { status, stdout, stderr })
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue