prism_parser/grammar/
escaped_string.rs1use serde::{Deserialize, Serialize};
2use std::borrow::Cow;
3use std::fmt::{Display, Formatter};
4use std::str::{Chars, FromStr};
5
6#[derive(Debug, Copy, Clone, Hash, Serialize, Deserialize, Eq, PartialEq)]
7pub struct EscapedString<'grm>(&'grm str);
8
9impl<'grm> EscapedString<'grm> {
10 pub fn from_escaped(s: &'grm str) -> Self {
11 Self(s)
12 }
13
14 pub fn to_cow(&self) -> Cow<'grm, str> {
15 if self.0.contains('\\') {
16 Cow::Owned(self.chars().collect())
17 } else {
18 Cow::Borrowed(self.0)
19 }
20 }
21
22 pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
23 EscapedStringIter(self.0.chars())
24 }
25
26 pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
27 self.0.parse()
28 }
29}
30
31impl Display for EscapedString<'_> {
32 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
33 write!(f, "{}", self.0)
34 }
35}
36
37struct EscapedStringIter<'grm>(Chars<'grm>);
38
39impl<'grm> Iterator for EscapedStringIter<'grm> {
40 type Item = char;
41
42 fn next(&mut self) -> Option<Self::Item> {
43 Some(match self.0.next()? {
44 '\\' => match self.0.next()? {
45 'n' => '\n',
46 'r' => '\r',
47 '\\' => '\\',
48 '"' => '"',
49 '\'' => '\'',
50 _ => panic!("Invalid escape sequence"),
51 },
52 c => c,
53 })
54 }
55}