Skip to content

Commit

Permalink
Fix a bug; update documentation and tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
TheVeryDarkness committed Sep 3, 2024
1 parent 1c727bf commit 65e812c
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 29 deletions.
4 changes: 2 additions & 2 deletions src/stdio/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{unwrap, BufReadExt};

/// Read a line from standard input. The trailing newline will be consumed and trimmed.
///
/// ```
/// ```txt
///
/// a b c
/// ```
Expand All @@ -13,7 +13,7 @@ pub fn get_line() -> String {

/// Read a non-empty line from standard input. The trailing newline will be consumed and trimmed.
///
/// ```
/// ```txt
///
/// a b c
/// ```
Expand Down
48 changes: 36 additions & 12 deletions src/stream/input_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,25 @@ impl<B: BufRead> InputStream<B> {
/// See [Self::fill_buf].
#[inline]
fn remove_leading(&mut self, pattern: &[char]) -> Result<(&str, usize), StreamError> {
if self.is_eol() {
let _read = self.read_buf()?;
let mut len_skipped = 0;
loop {
if self.is_eol() {
let read = self.read_buf()?;
if !read {
return Ok(("", len_skipped));
}
}
let remaining = as_slice_from(&self.line_buf, self.cursor);
let remaining_trimmed = remaining.trim_start_matches(pattern);
len_skipped += remaining.len() - remaining_trimmed.len();
self.cursor = self.line_buf.len() - remaining_trimmed.len();
debug_assert!(self.line_buf.is_char_boundary(self.cursor));
if self.is_eol() {
continue;
}
let remaining = unsafe { transmute(remaining_trimmed) };
return Ok((remaining, len_skipped));
}
let remaining = as_slice_from(&self.line_buf, self.cursor);
let len_skipped = remaining.len();
let remaining = remaining.trim_start_matches(pattern);
let len_skipped = len_skipped - remaining.len();
self.cursor = self.line_buf.len() - remaining.len();
debug_assert!(self.line_buf.is_char_boundary(self.cursor));
Ok((remaining, len_skipped))
}
}

Expand Down Expand Up @@ -185,7 +194,7 @@ mod tests {

#[test]
fn try_get() {
let s = "Hello, world!";
let s = "Hello, world!\nHello, Rust!";
let mut stream = InputStream::new(Cursor::new(s));
assert_eq!(stream.try_get().unwrap(), 'H');
assert_eq!(stream.try_get().unwrap(), 'e');
Expand All @@ -200,19 +209,34 @@ mod tests {
assert_eq!(stream.try_get().unwrap(), 'l');
assert_eq!(stream.try_get().unwrap(), 'd');
assert_eq!(stream.try_get().unwrap(), '!');
assert_eq!(stream.try_get().unwrap(), '\n');
assert_eq!(stream.try_get().unwrap(), 'H');
assert_eq!(stream.try_get().unwrap(), 'e');
assert_eq!(stream.try_get().unwrap(), 'l');
assert_eq!(stream.try_get().unwrap(), 'l');
assert_eq!(stream.try_get().unwrap(), 'o');
assert_eq!(stream.try_get().unwrap(), ',');
assert_eq!(stream.try_get().unwrap(), ' ');
assert_eq!(stream.try_get().unwrap(), 'R');
assert_eq!(stream.try_get().unwrap(), 'u');
assert_eq!(stream.try_get().unwrap(), 's');
assert_eq!(stream.try_get().unwrap(), 't');
assert_eq!(stream.try_get().unwrap(), '!');
assert!(
matches!(stream.try_get().unwrap_err(), StreamError::EOF),
"{:?}",
stream.try_get_string_some()
stream.try_get_string_some(),
);
}

#[test]
fn try_get_string() {
let s = "Hello, world!";
let s = "Hello, world!\nHello, Rust!";
let mut stream = InputStream::new(Cursor::new(s));
assert_eq!(stream.try_get_string_some().unwrap(), "Hello,");
assert_eq!(stream.try_get_string_some().unwrap(), "world!");
assert_eq!(stream.try_get_string_some().unwrap(), "Hello,");
assert_eq!(stream.try_get_string_some().unwrap(), "Rust!");
assert!(
matches!(stream.try_get_string_some().unwrap_err(), StreamError::EOF),
"{:?}",
Expand Down
12 changes: 8 additions & 4 deletions src/stream/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,21 +79,23 @@ pub trait BufReadExt {
/// If current line is empty or all ASCII-white-spaces, it will read a new line.
fn try_get_string_some(&mut self) -> Result<&str, StreamError>;

/// Get a single line. The trailing newline will be trimmed.
/// Get a single line. The trailing newline will be consumed and trimmed.
#[inline]
fn try_get_line(&mut self) -> Result<&str, StreamError> {
let line = self.try_get_until_in_line(&[])?;
Ok(line.trim_end_matches(EOL))
}

/// Get a single line. The trailing white-paces will be trimmed.
/// Get a single line. The trailing white spaces will be consumed and trimmed.
#[inline]
fn try_get_line_trimmed(&mut self) -> Result<&str, StreamError> {
let line = self.try_get_line()?;
Ok(line.trim_end_matches(WHITE))
}

/// Get a single not-empty line. Repeat reading a new line if current line is empty.
/// Get a single not-empty line. The trailing newline will be consumed and trimmed.
///
/// Repeat reading a new line if current line is empty.
#[inline]
fn try_get_line_some(&mut self) -> Result<&str, StreamError> {
loop {
Expand All @@ -105,7 +107,9 @@ pub trait BufReadExt {
}
}

/// Get a single not-empty line. The trailing white-spaces will be trimmed.
/// Get a single not-empty line. The trailing white spaces will be consumed and trimmed.
///
/// Repeat reading a new line if current line is empty.
#[inline]
fn try_get_line_some_trimmed(&mut self) -> Result<&str, StreamError> {
loop {
Expand Down
4 changes: 2 additions & 2 deletions tests/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ fn try_read_tuple_3_from_str_err() {

let vec: Result<(i32, i8, u32), _> = reader.try_read();
let err = vec.unwrap_err();
assert_eq!(err.to_string(), "invalid digit found in string");
assert_eq!(err.to_string(), "Error during converting a string \"-3\" to a value of `u32`: invalid digit found in string");
assert_eq!(
format!("{:?}", err),
"T3(ParseIntError { kind: InvalidDigit })"
"FromStrError(T3(ParseIntError { kind: InvalidDigit }), \"-3\", \"u32\")"
);
}

Expand Down
9 changes: 0 additions & 9 deletions tests/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,12 @@ fn read_one_then_read_0() {
let a: u32 = reader.read_one();
assert_eq!(a, 1);

let b: Vec<u32> = reader.read();
assert_eq!(b, []);

let a: u32 = reader.read_one();
assert_eq!(a, 2);

let b: Vec<u32> = reader.read();
assert_eq!(b, []);

let a: u32 = reader.read_one();
assert_eq!(a, 3);

let b: Vec<u32> = reader.read();
assert_eq!(b, []);

assert!(<u32>::try_read_from(&mut reader).is_err());
assert!(<Vec<u32>>::try_read_from(&mut reader).is_err());
assert!(<Vec<u32>>::try_read_from(&mut reader).is_err());
Expand Down

0 comments on commit 65e812c

Please sign in to comment.