utf8-bufread 1.0.0

Provides alternatives to BufRead's read_line & lines that stop not on newlines
Documentation
use std::io::{Cursor, ErrorKind, Read};
use std::str::Utf8Error;
use std::string::FromUtf8Error;
use utf8_bufread::BufRead;

#[test]
fn empty_str_after_eof() {
    let input = "The quick fox jumps over the lazy dog.";
    let mut v = Vec::with_capacity(input.len());
    let mut r = Cursor::new(input);
    assert!(r.read_to_end(&mut v).is_ok());
    // All subsequent calls to `read_str` will return the empty string
    for _ in 0..3 {
        let s = r.read_str();
        assert!(s.is_ok());
        let s = s.unwrap();
        assert!(s.is_empty());
    }
}

#[test]
fn invalid_codepoint() {
    let mut r = Cursor::new([0x9fu8, 0x92, 0x96, 0x0]);
    let e = r.read_str();
    assert!(e.is_err());
    let e = e.unwrap_err();
    assert_eq!(e.kind(), ErrorKind::InvalidData);
    let e = e.into_inner_lossy().unwrap();
    assert!(e.is::<Utf8Error>() || e.is::<FromUtf8Error>());
}

#[test]
fn eof_on_incomplete_codepoint() {
    let mut r = Cursor::new(&"💖".as_bytes()[..3]);
    let e = r.read_str();
    assert!(e.is_err());
    let e = e.unwrap_err();
    assert_eq!(e.kind(), ErrorKind::UnexpectedEof);
    assert!(e.into_inner_lossy().is_none());
}

#[test]
fn complete_successful_read() {
    let mut r = Cursor::new("b💖ä€");
    let s = r.read_str();
    assert!(s.is_ok());
    let s = s.unwrap();
    assert_eq!(s, "b💖ä€");
}

#[test]
fn incomplete_successful_read() {
    // "b💖ä€" but missing one byte at the end
    let mut r = Cursor::new(&"b💖ä€".as_bytes()[..9]);
    let s = r.read_str();
    assert!(s.is_ok());
    let s = s.unwrap();
    assert_eq!(s, "b💖ä");
}

#[test]
fn compile_fail_tests() {
    let t = trybuild::TestCases::new();
    t.compile_fail("tests/read_str/*.rs")
}