token-parser 0.7.0

Utilities for parsing texts into data structures
Documentation
use std::{rc::Rc, sync::Arc};

use token_parser::{ErrorKind, Parsable, Parser, Span, Unit};

fn symbol(name: &str) -> Unit {
    Unit::Symbol(name.into(), Span::default())
}

fn list<I: IntoIterator<Item = Unit>>(items: I) -> Unit {
    Unit::Parser(Parser::new(items))
}

fn parse_one<T: Parsable<()>>(unit: Unit) -> token_parser::Result<T> {
    let mut parser = Parser::new([unit]);
    parser.parse_next(&())
}

#[test]
fn parse_string() {
    let result: String = parse_one(symbol("hello")).unwrap();
    assert_eq!(result, "hello");
}

#[test]
fn parse_box_str() {
    let result: Box<str> = parse_one(symbol("world")).unwrap();
    assert_eq!(&*result, "world");
}

#[test]
fn parse_vec() {
    let result: Vec<String> = parse_one(list([symbol("a"), symbol("b"), symbol("c")])).unwrap();
    assert_eq!(result, vec!["a".to_string(), "b".into(), "c".into()]);
}

#[test]
fn parse_box() {
    let result: Box<String> = parse_one(symbol("x")).unwrap();
    assert_eq!(&**result, "x");
}

#[test]
fn parse_rc() {
    let result: Rc<String> = parse_one(symbol("x")).unwrap();
    assert_eq!(&**result, "x");
}

#[test]
fn parse_arc() {
    let result: Arc<String> = parse_one(symbol("x")).unwrap();
    assert_eq!(&**result, "x");
}

#[test]
fn parse_arc_nested_list() {
    let result: Arc<Vec<String>> = parse_one(list([symbol("a"), symbol("b")])).unwrap();
    assert_eq!(&**result, &["a".to_string(), "b".into()]);
}

#[test]
fn parse_bool() {
    let result: bool = parse_one(symbol("true")).unwrap();
    assert!(result);
}

#[test]
fn parse_symbol_not_allowed() {
    let error = parse_one::<Vec<String>>(symbol("a")).unwrap_err();
    assert!(matches!(error.kind, ErrorKind::SymbolNotAllowed));
}

#[test]
fn parse_list_not_allowed() {
    let error = parse_one::<String>(list([symbol("a")])).unwrap_err();
    assert!(matches!(error.kind, ErrorKind::ListNotAllowed));
}

#[test]
fn parse_not_enough() {
    let mut parser = Parser::new(Vec::<Unit>::new());
    let error = parser.parse_next::<(), String>(&()).unwrap_err();
    assert!(matches!(error.kind, ErrorKind::NotEnoughElements(_)));
}

#[test]
fn parse_too_many_with_parse_rest() {
    let mut parser = Parser::new([symbol("a"), symbol("b")]);
    let error = parser.parse_rest::<(), String>(&()).unwrap_err();
    assert!(matches!(error.kind, ErrorKind::TooManyElements(_)));
}

#[test]
fn substitute_replaces_symbols() {
    let mut unit = list([symbol("$x"), symbol("y")]);
    unit.substitute("$x", "z");
    let result: Vec<String> = parse_one(unit).unwrap();
    assert_eq!(result, vec!["z".to_string(), "y".into()]);
}