use serde::Deserialize;
use serde::Serialize;
use crate::lexer::token::lexeme::Lexeme;
use crate::lexer::token::lexeme::Literal;
use crate::lexer::token::location::Location;
use crate::lexer::token::Token;
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct String {
pub inner: std::string::String,
pub is_hexadecimal: bool,
}
impl String {
pub fn new(inner: ::std::string::String, is_hexadecimal: bool) -> Self {
Self {
inner,
is_hexadecimal,
}
}
pub fn parse(input: &str) -> Option<Token> {
let mut length = 0;
let is_string = input[length..].starts_with('"');
let is_hex_string = input[length..].starts_with(r#"hex""#);
if !is_string && !is_hex_string {
return None;
}
if is_string {
length += 1;
}
if is_hex_string {
length += r#"hex""#.len();
}
let mut string = std::string::String::new();
loop {
if input[length..].starts_with('\\') {
string.push(input.chars().nth(length).expect("Always exists"));
string.push(input.chars().nth(length + 1).expect("Always exists"));
length += 2;
continue;
}
if input[length..].starts_with('"') {
length += 1;
break;
}
string.push(input.chars().nth(length).expect("Always exists"));
length += 1;
}
let string = string
.strip_prefix('"')
.and_then(|string| string.strip_suffix('"'))
.unwrap_or(string.as_str())
.to_owned();
let literal = Self::new(string, is_hex_string);
let length = length
.try_into()
.expect("the YUL should be of reasonable size");
Some(Token::new(
Location::new(0, length),
Lexeme::Literal(Literal::String(literal)),
length,
))
}
}
impl std::fmt::Display for String {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.inner)
}
}