just/src/cooked_string.rs

52 lines
1.3 KiB
Rust
Raw Normal View History

2017-11-16 23:30:08 -08:00
use common::*;
#[derive(PartialEq, Debug)]
pub struct CookedString<'a> {
pub raw: &'a str,
2017-11-16 23:30:08 -08:00
pub cooked: String,
}
impl<'a> CookedString<'a> {
2017-11-17 17:28:06 -08:00
pub fn new(token: &Token<'a>) -> CompilationResult<'a, CookedString<'a>> {
let raw = &token.lexeme[1..token.lexeme.len() - 1];
2017-11-16 23:30:08 -08:00
if let TokenKind::RawString = token.kind {
Ok(CookedString {
cooked: raw.to_string(),
raw,
})
2017-11-16 23:30:08 -08:00
} else if let TokenKind::StringToken = token.kind {
let mut cooked = String::new();
let mut escape = false;
for c in raw.chars() {
if escape {
match c {
'n' => cooked.push('\n'),
'r' => cooked.push('\r'),
't' => cooked.push('\t'),
'\\' => cooked.push('\\'),
'"' => cooked.push('"'),
other => {
return Err(
token.error(CompilationErrorKind::InvalidEscapeSequence { character: other }),
)
}
2017-11-16 23:30:08 -08:00
}
escape = false;
continue;
}
if c == '\\' {
escape = true;
continue;
}
cooked.push(c);
}
Ok(CookedString { raw, cooked })
2017-11-16 23:30:08 -08:00
} else {
Err(token.error(CompilationErrorKind::Internal {
message: "cook_string() called on non-string token".to_string(),
2017-11-16 23:30:08 -08:00
}))
}
}
}