pub_just/
string_kind.rs

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  // Indented values must come before un-indented values, or else
11  // `Self::from_token_start` will incorrectly return indented = false
12  // for indented strings.
13  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}