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