parsr 1.0.4

a libary for simple parsing
use super::{Input, ReadError, Result};

#[inline(always)]
pub(super) fn default_read_at_least<I: ?Sized + Input>(input: &mut I, n: usize) -> Result<&str> {
    input.buffer_at_least(n).map(|_| input.read())
}

pub(super) fn default_consume_until<I: ?Sized + Input>(
    input: &mut I,
    chunk_size: usize,
    func: impl Fn(char) -> bool,
) -> Result<()> {
    if input.is_eof() {
        return Err(ReadError::EOF);
    }

    loop {
        if let Result::Err(ReadError::InvalidUtf8(err)) = input.buffer_at_least(chunk_size) {
            return Err(ReadError::InvalidUtf8(err));
        };

        if input.is_eof() {
            return Err(ReadError::EOF);
        }

        let read = input.read();

        for (i, c) in read.char_indices() {
            if func(c) {
                unsafe { input.consume(i) };
                return Ok(());
            }
        }

        unsafe { input.consume(read.len()) };
    }
}

pub(super) fn default_read_until<I: ?Sized + Input>(
    input: &mut I,
    chunk_size: usize,
    func: impl Fn(char) -> bool,
) -> Result<&str> {
    if input.is_eof() {
        return Err(ReadError::EOF);
    }

    let mut first_loop = true;
    let mut count = 0;

    loop {
        if let Result::Err(ReadError::InvalidUtf8(err)) = input.buffer_at_least(chunk_size) {
            return Err(ReadError::InvalidUtf8(err));
        };

        if input.is_eof() && first_loop {
            return Err(ReadError::EOF);
        }

        first_loop = false;

        let read = input.read();

        for (i, c) in read.char_indices() {
            if func(c) {
                let s = unsafe { str::from_utf8_unchecked(input.get_unchecked(count + i)) };

                return Ok(s);
            }
        }

        count += read.len();
    }
}

#[inline(always)]
pub(super) fn default_peek<I: ?Sized + Input>(input: &mut I) -> Result<char> {
    input
        .read_at_least(4)
        .map(|s| unsafe { s.chars().next().unwrap_unchecked() })
}