Skip to content

Instantly share code, notes, and snippets.

@ilopX
Last active August 2, 2022 19:53
Show Gist options
  • Select an option

  • Save ilopX/b1fc56f76c7036236224fc5af315273d to your computer and use it in GitHub Desktop.

Select an option

Save ilopX/b1fc56f76c7036236224fc5af315273d to your computer and use it in GitHub Desktop.
fn main() {
let mut editor = Editor::new();
let mut history = History::new();
input("one", &mut editor, &mut history);
input("_", &mut editor, &mut history);
input("two", &mut editor, &mut history);
undo_all(&mut editor, &mut history);
}
type Editor = String;
type History = Vec<Box<dyn Command>>;
fn input(text: &str, editor: &mut Editor, history: &mut History) {
let mut command = InputText::new(text);
println!("Execute InputText: '{}'", text);
command.execute(editor);
println!("editor: '{}'\n", editor);
history.push(Box::new(command));
}
fn undo_all(editor: &mut Editor, history: &mut History) {
for command in &mut history.iter_mut().rev() {
println!("After Undo.");
command.undo(editor);
println!("editor: '{}'\n", editor);
}
}
trait Command {
fn execute(&mut self, editor: &mut Editor);
fn undo(&mut self, _editor: &mut Editor) {}
fn is_save_history(&self) -> bool { false }
}
struct InputText {
text: String,
position: Option<usize>,
}
impl InputText {
fn new(text: &str) -> Self {
Self {
text: text.to_string(),
position: None,
}
}
}
impl Command for InputText {
fn execute(&mut self, editor: &mut Editor) {
if self.position != None {
return;
}
self.position = Some(editor.len());
editor.push_str(&self.text);
}
fn undo(&mut self, editor: &mut Editor) {
if let Some(start) = self.position {
let end = start + self.text.len();
editor.replace_range(start..end, "");
}
}
fn is_save_history(&self) -> bool { true }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment