tiger-lib 1.17.0

Library used by the tools ck3-tiger, vic3-tiger, and imperator-tiger. This library holds the bulk of the code for them. It can be built either for ck3-tiger with the feature ck3, or for vic3-tiger with the feature vic3, or for imperator-tiger with the feature imperator, but not both at the same time.
Documentation
use std::mem::take;

use crate::token::{Loc, Token};

/// Copy on boundary type used for when a token may cross multiple parts of the input.
#[derive(Clone, Debug, Default)]
pub(crate) enum Cob {
    #[default]
    Uninit,
    Borrowed(&'static str, usize, usize, Loc),
    Owned(String, Loc),
}

impl Cob {
    pub(crate) fn new() -> Self {
        Self::default()
    }

    #[inline]
    pub(crate) fn set(&mut self, str: &'static str, index: usize, loc: Loc) {
        *self = Self::Borrowed(str, index, index, loc);
    }

    /// **ASSERT**: the char must match the char starting at the end index of the borrowed string (if applicable).
    pub(crate) fn add_char(&mut self, c: char) {
        match *self {
            Self::Uninit => unreachable!(),
            Self::Borrowed(str, start, end, loc) if end == str.len() => {
                let mut string = str[start..].to_owned();
                string.push(c);
                *self = Self::Owned(string, loc);
            }
            Self::Borrowed(_str, _, ref mut end, _) => {
                // ASSERT: _str[*end..].starts_with(c)
                *end += c.len_utf8();
            }
            Self::Owned(ref mut string, _) => string.push(c),
        }
    }

    pub(crate) fn make_owned(&mut self) {
        match *self {
            Self::Uninit => unreachable!(),
            Self::Borrowed(str, start, end, loc) => {
                let string = str[start..end].to_owned();
                *self = Self::Owned(string, loc);
            }
            Self::Owned(_, _) => (),
        }
    }

    pub(crate) fn take_to_token(&mut self) -> Token {
        match take(self) {
            Cob::Uninit => unreachable!(),
            Cob::Borrowed(str, start, end, loc) => Token::from_static_str(&str[start..end], loc),
            Cob::Owned(string, loc) => Token::new(&string, loc),
        }
    }
}