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()]);
}