Parse Tokens With Spans Using chumsky In Rust

Code
#!/usr/bin/env cargo +nightly -Zscript

//! ```cargo
//! [package]
//! edition = "2021"
//! [dependencies]
//! chumsky = { version = "0.9.2" }
//! ```

use chumsky::prelude::*;
use chumsky::Parser;
use std::ops::Range;

#[derive(Debug)]
pub enum Token {
    LetterA,
    LetterB,
}

fn main() {
    let source = "abba";
    let result = letters().parse(source);
    dbg!(&result);
}

fn letters() -> impl Parser<char, Vec<(Token, Range<usize>)>, Error = Simple<char>> {
    letter1().or(letter2()).repeated()
}

fn letter1() -> impl Parser<char, (Token, Range<usize>), Error = Simple<char>> {
    just("a").map_with_span(|_, span| (Token::LetterA, span))
}

fn letter2() -> impl Parser<char, (Token, Range<usize>), Error = Simple<char>> {
    just("b").map_with_span(|_, span| (Token::LetterB, span))
}
Results
Ok(
    [
        (
            LetterA,
            0..1,
        ),
        (
            LetterB,
            1..2,
        ),
        (
            LetterB,
            2..3,
        ),
        (
            LetterA,
            3..4,
        ),
    ],
)
Notes
  • This is a test I'm doing for the Neopolitan LSP

  • Individual Token are created with their spans in `letter1`` and `letter2`` then assembled into a Vec in `letters``