You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
51 lines
1.4 KiB
Rust
51 lines
1.4 KiB
Rust
use crate::error::TapeResult;
|
|
use crate::traits::AsyncReadSeek;
|
|
use std::io::SeekFrom;
|
|
use tokio::io::{AsyncReadExt, BufReader};
|
|
use tokio::io::{AsyncSeekExt, ErrorKind};
|
|
|
|
/// An Input reader to asynchronously read a type
|
|
/// that implements AsyncBufRead and AsyncSeek.
|
|
pub struct InputReader {
|
|
inner: BufReader<Box<dyn AsyncReadSeek>>,
|
|
}
|
|
|
|
impl InputReader {
|
|
pub fn new<T: AsyncReadSeek + 'static>(inner: T) -> Self {
|
|
Self {
|
|
inner: BufReader::new(Box::new(inner)),
|
|
}
|
|
}
|
|
|
|
/// Reads the next char consuming it in the process
|
|
pub async fn consume(&mut self) -> TapeResult<char> {
|
|
self.read_next().await
|
|
}
|
|
|
|
/// Returns the next char without forwarding
|
|
pub async fn peek(&mut self) -> TapeResult<char> {
|
|
let char = self.read_next().await?;
|
|
self.inner.get_mut().seek(SeekFrom::Current(-1)).await?;
|
|
|
|
Ok(char)
|
|
}
|
|
|
|
/// Returns if EOF has been reached
|
|
pub async fn check_eof(&mut self) -> TapeResult<bool> {
|
|
let char = self.read_next().await?;
|
|
|
|
Ok(char == '\x00')
|
|
}
|
|
|
|
/// Reads the next char returning \x00 for EOF
|
|
async fn read_next(&mut self) -> TapeResult<char> {
|
|
let mut value = String::with_capacity(1);
|
|
|
|
match self.inner.read_to_string(&mut value).await {
|
|
Ok(_) => Ok(value.chars().next().unwrap()),
|
|
Err(e) if e.kind() == ErrorKind::UnexpectedEof => Ok('\x00'),
|
|
Err(e) => Err(e.into()),
|
|
}
|
|
}
|
|
}
|