use crate::token::Token;
use crate::lexer::LexerErrorType;
pub type ParseResult<'a> = Result<(Token<'a>, &'a str), LexerErrorType>;
static VALID_SYMBOLS: &'static str = ".,(){}[]+-*/%=<>~:;#^";
#[inline]
pub fn is_digit(character: char) -> bool {
character.is_digit(10)
}
#[inline]
pub fn is_hex_digit(character: char) -> bool {
character.is_digit(16)
}
#[inline]
pub fn is_identifier_start(character: char) -> bool {
character.is_alphabetic() || character == '_'
}
#[inline]
pub fn is_identifier_end(character: char) -> bool {
character.is_alphanumeric() || character == '_'
}
#[inline]
pub fn is_valid_symbol(character: char) -> bool {
VALID_SYMBOLS.find(character).is_some()
}
#[inline]
pub fn is_whitespace(character: char) -> bool {
character.is_whitespace()
}
pub fn accumulate_until<'a, F>(input: &'a str, func: F) -> (&'a str, &'a str)
where F: Fn(char) -> bool
{
input.char_indices()
.find(|(_, character)| func(*character))
.map(|(i, _)| input.split_at(i))
.unwrap_or((input, &""))
}
pub fn accumulate_while<'a, F>(input: &'a str, func: F) -> (&'a str, &'a str)
where F: Fn(char) -> bool
{
input.char_indices()
.find(|(_, character)| !func(*character))
.map(|(i, _)| input.split_at(i))
.unwrap_or((input, &""))
}
#[cfg(test)]
mod tests {
use super::*;
mod accumulate_until {
use super::*;
#[test]
fn returns_beginning_of_string_until_predicate_is_true() {
assert_eq!(("ab", "cde"), accumulate_until("abcde", |c| c == 'c'));
}
#[test]
fn returns_empty_str_if_predicate_is_true_at_first_call() {
assert_eq!(("", "abcde"), accumulate_until("abcde", |_| true));
}
#[test]
fn returns_whole_str_if_predicate_is_always_false() {
assert_eq!(("abcde", ""), accumulate_until("abcde", |_| false));
}
}
mod accumulate_while {
use super::*;
#[test]
fn returns_beginning_of_string_while_predicate_is_true() {
assert_eq!(("12", "ab"), accumulate_while("12ab", |c| c.is_digit(10)));
}
#[test]
fn returns_empty_str_if_predicate_is_false_at_first_call() {
assert_eq!(("", "abcde"), accumulate_while("abcde", |_| false));
}
#[test]
fn returns_whole_str_if_predicate_is_always_true() {
assert_eq!(("abcde", ""), accumulate_while("abcde", |_| true));
}
}
}