#[derive(Clone, Debug)] pub struct Lexeme { text: String, pub next: String, } impl Lexeme { pub fn new(raw: &str, next: &str) -> Lexeme { Lexeme { text: raw.to_owned(), next: next.to_owned(), } } pub fn text(&self) -> String { self.text.clone() } pub fn is_whitespace(&self) -> bool { self.text == " " || self.text == "\n" } pub fn is_next_whitespace(&self) -> bool { self.next == " " || self.next == "\n" } pub fn match_first_char(&self, query: char) -> bool { if let Some(first) = self.text.chars().nth(0) { first == query } else { false } } pub fn next_first_char(&self) -> Option { self.next.chars().nth(0) } /// # Panics /// Panics if number of chars for a single lexeme exceeds `i2::MAX` pub fn count_char(&self, c: char) -> i32 { let count = self.text().chars().filter(|&n| n == c).count(); match i32::try_from(count) { Ok(i) => i, Err(e) => { panic!("Wild char number {count} is a bit much: {e:#?}"); }, } } pub fn split_chars(&self) -> Vec { let vector: Vec = self.text().chars().collect(); vector } pub fn split_words(self) -> Vec { self.text().split(' ').map(str::to_string).collect() } pub fn first(self) -> Option { self.split_words().first().map(String::to_owned) } pub fn collect(raw_strings: &[String]) -> Vec { let mut out_vector = Vec::with_capacity(raw_strings.len()); let mut iterator = raw_strings.iter().peekable(); while let Some(raw) = iterator.next() { let next = iterator.peek().map(|s| (*s).clone()).unwrap_or_default(); out_vector.push(Lexeme { text: raw.to_owned(), next, }); } out_vector } }