pub struct InterruptReader<R> { /* private fields */ }Expand description
An interruptable, buffered Reader.
This reader is created by wrapping a Read struct in the
interrupt_read::pair function, which also returns an
Interruptor, which is capable of sending interrupt signals,
which make any read operations on the InterruptReader return
an error of kind ErrorKind::Other, with a payload of
InterruptReceived.
When an interrupt is received, the underlying data is not lost, it still exists, and if you call a reading function again, it will be retrieved, unless another interrupt is sent before that.
You can check if an std::io::Error is of this type by
calling the is_interrupt function.
§Examples
One potential application of this struct is if you want to stop a thread that is reading from the stdout of a child process without necessarily terminating said childrop_:
use std::{
io::{BufRead, ErrorKind},
process::{Child, Command, Stdio},
time::Duration,
};
use interrupt_read::{is_interrupt, pair};
struct ChildKiller(Child);
impl Drop for ChildKiller {
fn drop(&mut self) {
_ = self.0.kill();
}
}
// Prints "hello\n" every second forever.
let mut child = Command::new("bash")
.args(["-c", r#"while true; do echo "hello"; sleep 1; done"#])
.stdout(Stdio::piped())
.spawn()
.unwrap();
let (mut stdout, interruptor) = pair(child.stdout.take().unwrap());
let _child_killer = ChildKiller(child);
let join_handle = std::thread::spawn(move || {
let mut string = String::new();
loop {
match stdout.read_line(&mut string) {
Ok(0) => break Ok(string),
Ok(_) => {}
Err(err) if is_interrupt(&err) => {
break Ok(string);
}
Err(err) => break Err(err),
}
}
});
std::thread::sleep(Duration::new(3, 1_000_000));
interruptor.interrupt()?;
let result = join_handle.join().unwrap()?;
assert_eq!(result, "hello\nhello\nhello\n");
Ok(())Implementations§
Source§impl<R: Read> InterruptReader<R>
impl<R: Read> InterruptReader<R>
Sourcepub fn into_inner(self) -> Result<R>
pub fn into_inner(self) -> Result<R>
Unwraps this InterruptReader, returning the underlying
reader.
Note that any leftover data in the internal buffer is lost. Therefore, a following read from the underlying reader may lead to data loss.
This may return Err if the underlying joined thread has
panicked, probably because the Reader has done so.
Sourcepub fn is_reading(&self) -> bool
pub fn is_reading(&self) -> bool
Wether the reader thread is still active.
Trait Implementations§
Source§impl<R: Read> BufRead for InterruptReader<R>
impl<R: Read> BufRead for InterruptReader<R>
Source§fn fill_buf(&mut self) -> Result<&[u8]>
fn fill_buf(&mut self) -> Result<&[u8]>
Read methods, if empty. Read moreSource§fn consume(&mut self, amount: usize)
fn consume(&mut self, amount: usize)
amount of additional bytes from the internal buffer as having been read.
Subsequent calls to read only return bytes that have not been marked as read. Read moreSource§fn has_data_left(&mut self) -> Result<bool, Error>
fn has_data_left(&mut self) -> Result<bool, Error>
buf_read_has_data_left)read. Read more1.83.0 · Source§fn skip_until(&mut self, byte: u8) -> Result<usize, Error>
fn skip_until(&mut self, byte: u8) -> Result<usize, Error>
byte or EOF is reached. Read more1.0.0 · Source§fn read_line(&mut self, buf: &mut String) -> Result<usize, Error>
fn read_line(&mut self, buf: &mut String) -> Result<usize, Error>
0xA byte) is reached, and append
them to the provided String buffer. Read moreSource§impl<R: Debug> Debug for InterruptReader<R>
impl<R: Debug> Debug for InterruptReader<R>
Source§impl<R: Read> Read for InterruptReader<R>
impl<R: Read> Read for InterruptReader<R>
Source§fn read(&mut self, buf: &mut [u8]) -> Result<usize>
fn read(&mut self, buf: &mut [u8]) -> Result<usize>
1.36.0 · Source§fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>
read, except that it reads into a slice of buffers. Read moreSource§fn is_read_vectored(&self) -> bool
fn is_read_vectored(&self) -> bool
can_vector)1.0.0 · Source§fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>
buf. Read more1.0.0 · Source§fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>
fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>
buf. Read more1.6.0 · Source§fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>
buf. Read moreSource§fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>
fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>
read_buf)Source§fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>
read_buf)cursor. Read more1.0.0 · Source§fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
Read. Read more