1use std::mem::take;
2
3use crate::token::{Loc, Token};
4
5#[derive(Clone, Debug, Default)]
7pub(crate) enum Cob {
8 #[default]
9 Uninit,
10 Borrowed(&'static str, usize, usize, Loc),
11 Owned(String, Loc),
12}
13
14impl Cob {
15 pub(crate) fn new() -> Self {
16 Self::default()
17 }
18
19 #[inline]
20 pub(crate) fn set(&mut self, str: &'static str, index: usize, loc: Loc) {
21 *self = Self::Borrowed(str, index, index, loc);
22 }
23
24 pub(crate) fn add_char(&mut self, c: char) {
26 match *self {
27 Self::Uninit => unreachable!(),
28 Self::Borrowed(str, start, end, loc) if end == str.len() => {
29 let mut string = str[start..].to_owned();
30 string.push(c);
31 *self = Self::Owned(string, loc);
32 }
33 Self::Borrowed(_str, _, ref mut end, _) => {
34 *end += c.len_utf8();
36 }
37 Self::Owned(ref mut string, _) => string.push(c),
38 }
39 }
40
41 pub(crate) fn make_owned(&mut self) {
42 match *self {
43 Self::Uninit => unreachable!(),
44 Self::Borrowed(str, start, end, loc) => {
45 let string = str[start..end].to_owned();
46 *self = Self::Owned(string, loc);
47 }
48 Self::Owned(_, _) => (),
49 }
50 }
51
52 pub(crate) fn take_to_token(&mut self) -> Token {
53 match take(self) {
54 Cob::Uninit => unreachable!(),
55 Cob::Borrowed(str, start, end, loc) => Token::from_static_str(&str[start..end], loc),
56 Cob::Owned(string, loc) => Token::new(&string, loc),
57 }
58 }
59}