udled-tokenizers 0.8.0

Tokenizers for udled
Documentation
use udled::{AsBytes, AsChar, AsSlice, Buffer, Char, Item, Tokenizer, TokenizerExt};

#[derive(Debug, Clone, Copy)]
pub struct Whitespace;

impl<'input, T> Tokenizer<'input, T> for Whitespace
where
    T: Buffer<'input>,
    T::Item: AsChar,
{
    type Token = Item<char>;

    fn to_token(
        &self,
        reader: &mut udled::Reader<'_, 'input, T>,
    ) -> Result<Self::Token, udled::Error> {
        let char = reader.parse(Char)?;
        if char.value.is_whitespace() {
            Ok(char)
        } else {
            Err(reader.error("Whitespace"))
        }
    }

    fn eat(&self, reader: &mut udled::Reader<'_, 'input, T>) -> Result<(), udled::Error> {
        let _ = self.to_token(reader)?;
        Ok(())
    }

    fn peek(&self, reader: &mut udled::Reader<'_, 'input, T>) -> bool {
        let Ok(ret) = reader.parse(Char) else {
            return false;
        };

        ret.value.is_whitespace()
    }
}

#[derive(Debug, Clone, Copy)]
pub struct AsciiWhitespace;

impl<'input, T> Tokenizer<'input, T> for AsciiWhitespace
where
    T: Buffer<'input>,
    T::Item: AsChar,
{
    type Token = Item<char>;

    fn to_token(
        &self,
        reader: &mut udled::Reader<'_, 'input, T>,
    ) -> Result<Self::Token, udled::Error> {
        let char = reader.parse(Char)?;
        if char.value.is_ascii_whitespace() {
            Ok(char)
        } else {
            Err(reader.error("Whitespace"))
        }
    }

    fn eat(&self, reader: &mut udled::Reader<'_, 'input, T>) -> Result<(), udled::Error> {
        let _ = self.to_token(reader)?;
        Ok(())
    }

    fn peek(&self, reader: &mut udled::Reader<'_, 'input, T>) -> bool {
        let Ok(ret) = reader.parse(Char) else {
            return false;
        };

        ret.value.is_ascii_whitespace()
    }
}

#[derive(Debug, Clone, Copy)]
pub struct LineFeed;

impl<'input, T> Tokenizer<'input, T> for LineFeed
where
    T: Buffer<'input>,
    T::Item: AsChar,
    T::Source: AsBytes<'input> + AsSlice<'input>,
{
    type Token = Item<<T::Source as AsSlice<'input>>::Slice>;

    fn to_token(
        &self,
        reader: &mut udled::Reader<'_, 'input, T>,
    ) -> Result<Self::Token, udled::Error> {
        let Ok(char) = reader.parse('\n'.or('\r').or('\u{2028}').or('\u{2029}').slice()) else {
            return Err(reader.error("Line Feed"));
        };
        Ok(char)
    }

    fn eat(&self, reader: &mut udled::Reader<'_, 'input, T>) -> Result<(), udled::Error> {
        let _ = self.to_token(reader)?;
        Ok(())
    }

    fn peek(&self, reader: &mut udled::Reader<'_, 'input, T>) -> bool {
        reader.is('\n'.or('\r').or('\u{2028}').or('\u{2029}'))
    }
}

#[derive(Debug, Clone, Copy)]
pub struct Space;

impl<'input, T> Tokenizer<'input, T> for Space
where
    T: Buffer<'input>,
    T::Item: AsChar,
{
    type Token = Item<char>;

    fn to_token(
        &self,
        reader: &mut udled::Reader<'_, 'input, T>,
    ) -> Result<Self::Token, udled::Error> {
        let char = reader.parse(' '.or('\t'))?.unify();
        Ok(char)
    }

    fn eat(&self, reader: &mut udled::Reader<'_, 'input, T>) -> Result<(), udled::Error> {
        let _ = self.to_token(reader)?;
        Ok(())
    }

    fn peek(&self, reader: &mut udled::Reader<'_, 'input, T>) -> bool {
        reader.is(' '.or('\t'))
    }
}