17 unstable releases (3 breaking)

✓ Uses Rust 2018 edition

0.4.2 Jul 12, 2019
0.3.4 Jun 29, 2019
0.3.1 Mar 30, 2019
0.2.4 Dec 19, 2018
0.2.1 Nov 25, 2018
Download history 141/week @ 2019-03-29 141/week @ 2019-04-05 143/week @ 2019-04-12 131/week @ 2019-04-19 138/week @ 2019-04-26 158/week @ 2019-05-03 152/week @ 2019-05-10 241/week @ 2019-05-17 278/week @ 2019-05-24 199/week @ 2019-05-31 354/week @ 2019-06-07 309/week @ 2019-06-14 518/week @ 2019-06-21 547/week @ 2019-06-28 393/week @ 2019-07-05

1,209 downloads per month
Used in 1 crate

MIT/Apache

26KB
391 lines

uwl

A crate for providing a simple way of streaming over characters without giving a damn about unicode.

License

Licensed under either of

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


lib.rs:

A stream of chars for building such as a lexer. Making the step of "iteration between characters" considerably easier. And providing certain utilites for making the code simpler. Respects both ASCII and Unicode.

Example, lexing identifiers, numbers and some punctuation marks:

use uwl::AsciiStream;
use uwl::StrExt;

#[derive(Debug, PartialEq)]
enum TokenKind {
    Ident,
    Number,
    Question,
    Exclamation,
    Comma,
    Point,

    // An invalid token
    Illegal,
}

#[derive(Debug, PartialEq)]
struct Token<'a> {
    kind: TokenKind,
    lit: &'a str,
}

impl<'a> Token<'a> {
    fn new(kind: TokenKind, lit: &'a str) -> Self {
        Token {
            kind,
            lit,
        }
    }
}

fn lex<'a>(stream: &mut AsciiStream<'a>) -> Option<Token<'a>> {
    if stream.at_end() {
        return None;
    }

    Some(match stream.current()? {
        // Ignore whitespace.
        s if s.is_whitespace() => {
            stream.next()?;
            return lex(stream);
        },
        s if s.is_alphabetic() => Token::new(TokenKind::Ident, stream.take_while(|s| s.is_alphabetic())),
        s if s.is_numeric() => Token::new(TokenKind::Number, stream.take_while(|s| s.is_numeric())),
        "?" => Token::new(TokenKind::Question, stream.next()?),
        "!" => Token::new(TokenKind::Exclamation, stream.next()?),
        "," => Token::new(TokenKind::Comma, stream.next()?),
        "." => Token::new(TokenKind::Point, stream.next()?),
        _ => Token::new(TokenKind::Illegal, stream.next()?),
    })
}

fn main() {
    let mut stream = AsciiStream::new("Hello, world! ...world? Hello?");

    assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Ident, "Hello")));
    assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Comma, ",")));
    assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Ident, "world")));
    assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Exclamation, "!")));
    assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Point, ".")));
    assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Point, ".")));
    assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Point, ".")));
    assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Ident, "world")));
    assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Question, "?")));
    assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Ident, "Hello")));
    assert_eq!(lex(&mut stream), Some(Token::new(TokenKind::Question, "?")));

    // Reached the end
    assert_eq!(lex(&mut stream), None);
}

No runtime deps