Add consume method to reader

Signed-off-by: trivernis <trivernis@protonmail.com>
master
trivernis 3 years ago
parent 4301930b1b
commit e5dac6bdba
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,6 +1,6 @@
[package] [package]
name = "charred" name = "charred"
version = "2.1.1" version = "2.2.0"
authors = ["trivernis <trivernis@protonmail.com>"] authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018" edition = "2018"
license-file = "LICENSE" license-file = "LICENSE"

@ -9,4 +9,7 @@ pub enum TapeError {
#[error("Unexpected EOF")] #[error("Unexpected EOF")]
EOF, EOF,
#[error("Failed to read char at current index")]
IndexError,
} }

@ -11,6 +11,7 @@ pub struct InputReader {
} }
impl InputReader { impl InputReader {
/// Creates a new Input Reader
pub fn new<T: AsyncBufRead + Unpin + Send + 'static>(inner: T) -> Self { pub fn new<T: AsyncBufRead + Unpin + Send + 'static>(inner: T) -> Self {
Self { Self {
inner: Box::new(inner), inner: Box::new(inner),
@ -22,13 +23,16 @@ impl InputReader {
/// Reads the next char consuming it in the process /// Reads the next char consuming it in the process
#[inline] #[inline]
pub async fn consume(&mut self) -> TapeResult<char> { pub async fn consume(&mut self) -> TapeResult<char> {
self.read_next().await self.seek_to(self.index + 1).await?;
self.read_current().await
} }
/// Returns the next char without forwarding /// Returns the next char without forwarding
#[inline] #[inline]
pub async fn peek(&mut self) -> TapeResult<char> { pub async fn peek(&mut self) -> TapeResult<char> {
let char = self.read_next().await?; self.seek_to(self.index + 1).await?;
let char = self.read_current().await?;
self.seek_to(self.index - 1).await?; self.seek_to(self.index - 1).await?;
Ok(char) Ok(char)
@ -44,18 +48,10 @@ impl InputReader {
} }
} }
/// Reads the next char returning \x00 for EOF /// Returns the previous char
async fn read_next(&mut self) -> TapeResult<char> { #[inline]
self.seek_to(self.index + 1).await?; pub async fn previous(&mut self) -> Option<char> {
let result = self self.read_current().await.ok()
.buf
.get(self.index - 1..self.index)
.ok_or(TapeError::EOF)?
.chars()
.next()
.ok_or(TapeError::EOF);
result
} }
/// Seeks to a given index /// Seeks to a given index
@ -83,4 +79,20 @@ impl InputReader {
pub fn index(&self) -> usize { pub fn index(&self) -> usize {
self.index self.index
} }
/// Reads the next char returning \x00 for EOF
async fn read_current(&mut self) -> TapeResult<char> {
if self.index == 0 {
return Err(TapeError::IndexError);
}
let result = self
.buf
.get(self.index - 1..self.index)
.ok_or(TapeError::EOF)?
.chars()
.next()
.ok_or(TapeError::EOF);
result
}
} }

@ -15,6 +15,17 @@ async fn it_peeks() {
assert_eq!(reader.peek().await.unwrap(), 'A'); assert_eq!(reader.peek().await.unwrap(), 'A');
} }
#[tokio::test]
async fn it_reads_the_previous() {
let mut reader = get_reader();
assert!(reader.previous().await.is_none());
reader.consume().await.unwrap();
assert_eq!(reader.previous().await.unwrap(), 'A');
assert_eq!(reader.previous().await.unwrap(), 'A');
reader.consume().await.unwrap();
assert_eq!(reader.previous().await.unwrap(), 'B');
}
#[tokio::test] #[tokio::test]
async fn it_consumes() { async fn it_consumes() {
let mut reader = get_reader(); let mut reader = get_reader();

Loading…
Cancel
Save