Skip to content

Commit

Permalink
README: Tweak, add a note on safety and alternatives
Browse files Browse the repository at this point in the history
  • Loading branch information
Freaky committed Sep 13, 2019
1 parent 3ec85d5 commit 037edec
Showing 1 changed file with 28 additions and 11 deletions.
39 changes: 28 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ faster, less error-prone alternative to `BufRead::read_until`.

It provides three main functions:

### `next_line() -> Option<io::Result<&[u8]>>`

### `next_line()`

Returns `Option<io::Result<&[u8]>>` - `None` on end-of-file, an IO error from the
wrapped reader, or an immutable byte slice ending on and including any delimiter.
Returns `None` on end-of-file, or an `io::Result`-wrapped byte slice of the next
line from the reader.

Line length is limited to the size of the internal buffer - longer lines will be
spread across multiple reads.
Expand All @@ -21,20 +20,17 @@ use of `Option`; line length is naturally limited to some sensible value without
the use of `by_ref().take(limit)`; copying is minimised by returning borrowed
slices; you'll never forget to call `buf.clear()`.


### `next_batch()`
### `next_batch() -> Option<io::Result<&[u8]>>`

Behaves identically to `next_line()`, except it returns a slice of *all* the
complete lines in the buffer.

### `for_each() -> io::Result<()>`

### `for_each()`

Calls a closure on each line of the input, while the closure returns true and
no IO errors are detected. Such errors terminate iteration and are returned
Calls a closure on each line of the input, while the closure returns `Ok(true)`
and no IO errors are detected. Such errors terminate iteration and are returned
from the function.


## Example

```rust
Expand All @@ -55,6 +51,27 @@ while let Some(line) = reader.next_line() {
}
```

## Safety

`LineReader` contains no `unsafe` code, but it does hand out manually-calculated
slice positions from an internal buffer, and the only enforcement Rust performs
is to ensure they remain within that buffer.

There is no incomplete line detection, and as documented, lines that extend
beyond the configured buffer can be spread across multiple "lines", with only
the lack of a terminating delimiter as a hint. Care should be taken that this
doesn't cause undesired behaviour in code using the library.

Methods such as `get_mut()` offer direct access to the wrapped reader, and their
use without also calling `reset()` could result in undesired behaviour if the
reader's state is changed.

## Alternatives

[bstr](https://crates.io/crates/bstr): as of 0.2.8 the `for_byte_line` and
`for_byte_line_with_terminator` `BufRead` extension trait functions should
perform similarly, without `LineReader`'s line length limitations.

## Performance

Tests performed using ['Dickens_Charles_Pickwick_Papers.xml'](http://hur.st/Dickens_Charles_Pickwick_Papers.xml.xz),
Expand Down

0 comments on commit 037edec

Please sign in to comment.