#[derive(Debug)] pub struct CommandBox { pub enabled: bool, pub history: Vec, pub text: String, pub cursor: usize, } // cursor value of 0 is behind all text // cursor value of n is after n characters (insert after index n - 1) // cursor value of text.len() is after all text impl CommandBox { pub fn new() -> Self { CommandBox { enabled: false, history: vec![], text: String::new(), cursor: 0, } } pub fn forward(&mut self) { if self.cursor < self.text.len() { self.cursor += 1; } } pub fn backward(&mut self) { self.cursor = self.cursor.saturating_sub(1); } pub fn backspace(&mut self) { if self.cursor != 0 { self.text.remove(self.cursor - 1); self.backward(); } } pub fn delete(&mut self) { if self.cursor < self.text.len() { self.text.remove(self.cursor); } } pub fn push_str(&mut self, v: &str) { self.text.push_str(v); self.cursor += v.len(); } pub fn is_empty(&self) -> bool { self.text.is_empty() } pub fn clear(&mut self) { self.text.clear(); self.cursor = 0; } } #[cfg(test)] mod tests { use super::*; fn setup_with(text: &str) -> CommandBox { let mut cmd = CommandBox::new(); cmd.push_str(text); cmd } #[test] fn entering_text() { let cmd = setup_with("save as file.png"); assert_eq!(&cmd.text, "save as file.png"); assert_eq!(cmd.cursor, 16) } #[test] fn backspacing_from_end() { let mut cmd = setup_with("save"); cmd.backspace(); assert_eq!(&cmd.text, "sav"); assert_eq!(cmd.cursor, 3); } #[test] fn backspacing_from_middle() { let mut cmd = setup_with("save"); cmd.backward(); cmd.backspace(); assert_eq!(&cmd.text, "sae"); assert_eq!(cmd.cursor, 2); } #[test] fn delete() { let mut cmd = setup_with("save"); cmd.backward(); cmd.delete(); assert_eq!(&cmd.text, "sav"); assert_eq!(cmd.cursor, 3); } #[test] fn delete_end() { let mut cmd = setup_with("save"); cmd.delete(); assert_eq!(&cmd.text, "save"); } #[test] fn delete_all() { let mut cmd = setup_with("save"); for _ in 0..4 { cmd.backward(); } for _ in 0..4 { cmd.delete(); } assert_eq!(&cmd.text, ""); assert_eq!(cmd.cursor, 0); } #[test] fn seeking() { let mut cmd = setup_with("save"); for _ in 0..4 { cmd.backward(); } assert_eq!(cmd.cursor, 0); cmd.forward(); assert_eq!(cmd.cursor, 1); } }