-
Notifications
You must be signed in to change notification settings - Fork 531
/
Copy pathstring_kind.rs
85 lines (74 loc) · 2.57 KB
/
string_kind.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use super::*;
#[derive(Debug, PartialEq, Clone, Copy, Ord, PartialOrd, Eq)]
pub(crate) struct StringKind {
pub(crate) delimiter: StringDelimiter,
pub(crate) indented: bool,
}
impl StringKind {
// Indented values must come before un-indented values, or else
// `Self::from_token_start` will incorrectly return indented = false
// for indented strings.
const ALL: &'static [Self] = &[
Self::new(StringDelimiter::Backtick, true),
Self::new(StringDelimiter::Backtick, false),
Self::new(StringDelimiter::QuoteDouble, true),
Self::new(StringDelimiter::QuoteDouble, false),
Self::new(StringDelimiter::QuoteSingle, true),
Self::new(StringDelimiter::QuoteSingle, false),
];
const fn new(delimiter: StringDelimiter, indented: bool) -> Self {
Self {
delimiter,
indented,
}
}
pub(crate) fn delimiter(self) -> &'static str {
match (self.delimiter, self.indented) {
(StringDelimiter::Backtick, false) => "`",
(StringDelimiter::Backtick, true) => "```",
(StringDelimiter::QuoteDouble, false) => "\"",
(StringDelimiter::QuoteDouble, true) => "\"\"\"",
(StringDelimiter::QuoteSingle, false) => "'",
(StringDelimiter::QuoteSingle, true) => "'''",
}
}
pub(crate) fn delimiter_len(self) -> usize {
self.delimiter().len()
}
pub(crate) fn token_kind(self) -> TokenKind {
match self.delimiter {
StringDelimiter::QuoteDouble | StringDelimiter::QuoteSingle => TokenKind::StringToken,
StringDelimiter::Backtick => TokenKind::Backtick,
}
}
pub(crate) fn unterminated_error_kind(self) -> CompileErrorKind<'static> {
match self.delimiter {
StringDelimiter::QuoteDouble | StringDelimiter::QuoteSingle => {
CompileErrorKind::UnterminatedString
}
StringDelimiter::Backtick => CompileErrorKind::UnterminatedBacktick,
}
}
pub(crate) fn processes_escape_sequences(self) -> bool {
match self.delimiter {
StringDelimiter::QuoteDouble => true,
StringDelimiter::Backtick | StringDelimiter::QuoteSingle => false,
}
}
pub(crate) fn indented(self) -> bool {
self.indented
}
pub(crate) fn from_string_or_backtick(token: Token) -> CompileResult<Self> {
Self::from_token_start(token.lexeme()).ok_or_else(|| {
token.error(CompileErrorKind::Internal {
message: "StringKind::from_token: Expected String or Backtick".to_owned(),
})
})
}
pub(crate) fn from_token_start(token_start: &str) -> Option<Self> {
Self::ALL
.iter()
.find(|&&kind| token_start.starts_with(kind.delimiter()))
.copied()
}
}