lexer/unescaped.rs
1//! Utilities for unescaping strings
2
3use std::{char, str::Chars};
4
5/// Escapes the given char.
6///
7/// # Example
8/// ```
9/// use lexer::unescaped::escape_char;
10/// assert_eq!(Some('\n'), escape_char('n'));
11/// /* \g is NOT a valid escape character */
12/// assert_eq!(None, escape_char('g'));
13/// ```
14pub const fn escape_char(c: char) -> Option<char> {
15 let c = match c {
16 'n' => '\n',
17 'r' => '\r',
18 't' => '\t',
19 '\\' => '\\',
20 '\'' => '\'',
21 '"' => '\"',
22 _ => return None,
23 };
24 Some(c)
25}
26
27/// Iterator that takes a string and outputs it's characters,
28/// unescaping them if necessary.
29///
30/// This means, if the string contains the characters '\\' 'n',
31/// this iterator would return a single character '\n'
32pub struct Unescaped<'src> {
33 chars: Chars<'src>,
34}
35
36impl Iterator for Unescaped<'_> {
37 type Item = char;
38
39 fn next(&mut self) -> Option<Self::Item> {
40 let c = self.chars.next()?;
41 if c == '\\' {
42 escape_char(self.chars.next()?)
43 } else {
44 Some(c)
45 }
46 }
47}
48
49impl<'src> From<&'src str> for Unescaped<'src> {
50 fn from(value: &'src str) -> Self {
51 Self {
52 chars: value.chars(),
53 }
54 }
55}