1use std::any::Any;
2use std::fmt::Debug;
3use std::ops::Range;
4use std::path::PathBuf;
5
6use crate::error::DocError;
7use crate::files::Files;
8
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct Caret {
11 pub file: PathBuf,
12 pub selection: Range<usize>,
13}
14
15pub trait Edit: Any + Debug {
16 fn label(&self) -> &str;
17
18 fn files(&self) -> Vec<PathBuf>;
19
20 fn apply(&mut self, files: &mut Files) -> Result<(), DocError>;
21
22 fn inverse(&self) -> Box<dyn Edit>;
23
24 fn merge(&self, _next: &dyn Edit) -> Option<Box<dyn Edit>> {
25 None
26 }
27
28 fn caret(&self) -> Option<Caret> {
29 None
30 }
31}
32
33pub fn downcast<T: Edit>(edit: &dyn Edit) -> Option<&T> {
34 let any: &dyn Any = edit;
35 any.downcast_ref::<T>()
36}