use super::{token::Token, token::TokenTy, Lexer};
use std::str::Chars;
pub fn try_consume_quoted_literal(lexer: &mut Lexer) -> Option<Token> {
let mut chars: Chars = lexer.remaining.chars();
let first: char = chars.next().filter(|c| ['\'', '"', '`'].contains(c))?;
let mut bytes_consumed: usize = first.len_utf8();
let mut is_terminated: bool = false;
while let Some(consumed) = chars.next() {
bytes_consumed += consumed.len_utf8();
if consumed == first {
is_terminated = true;
break;
}
if consumed == '\\' {
bytes_consumed += chars.next().map(char::len_utf8).unwrap_or(0);
}
}
let variant: TokenTy = match first {
'\'' => TokenTy::CharLiteral {
terminated: is_terminated,
},
'\"' => TokenTy::StringLiteral {
terminated: is_terminated,
},
'`' => TokenTy::FormatStringLiteral {
terminated: is_terminated,
},
_ => unreachable!("There are no other quoted literals"),
};
Some(lexer.split_token_unchecked(bytes_consumed, variant))
}
#[cfg(test)]
mod tests {
use super::super::{token::TokenTy, Lexer};
#[test]
fn string_literal() {
let mut lexer = Lexer::new_test(r#""Test string literal""#);
let token = lexer.next_token().unwrap();
assert_eq!(token.variant, TokenTy::StringLiteral { terminated: true });
assert_eq!(token.fragment.as_str(), "\"Test string literal\"");
}
}