1use super::history::{change::Change, History};
2
3#[derive(Debug, Clone, Default)]
4pub struct Data {
5 bytes: Vec<u8>,
6 history: History,
7 dirty: bool,
8}
9
10impl Data {
11 pub fn new(bytes: Vec<u8>, history_limit: usize) -> Self {
12 Self {
13 bytes,
14 history: History::with_limit(history_limit),
15 dirty: false,
16 }
17 }
18
19 pub fn get(&self, i: usize) -> Option<u8> {
20 self.bytes.get(i).copied()
21 }
22
23 pub fn set(&mut self, i: usize, byte: u8) -> Result<(), mlua::Error> {
24 match self.bytes.get_mut(i) {
25 Some(b) => {
26 self.history.push(Change::new(i, &[*b], &[byte]));
27 *b = byte;
28 self.dirty = true;
29 Ok(())
30 }
31 None => Err(mlua::Error::external("index out of bounds")),
32 }
33 }
34
35 pub fn bytes(&self) -> &[u8] {
36 &self.bytes
37 }
38
39 pub fn dirty(&self) -> bool {
40 self.dirty
41 }
42
43 pub fn reset_dirty(&mut self) {
44 self.dirty = false;
45 }
46
47 pub fn push_change(&mut self, offset: usize, mut new: Vec<u8>) -> usize {
51 if offset >= self.bytes.len() {
52 panic!(
53 "Offset {} out of bounds for data of length {}",
54 offset,
55 self.bytes.len()
56 );
57 }
58 new.truncate(self.bytes.len().checked_sub(offset).unwrap());
59 let old = &self.bytes[offset..offset + new.len()];
60 if old == new.as_slice() {
61 return 0;
62 }
63 self.history.push(Change::new(offset, old, &new));
64 self.bytes[offset..offset + new.len()].copy_from_slice(&new);
65 self.dirty = true;
66 new.len()
67 }
68
69 pub fn undo(&mut self) -> Option<&Change> {
72 self.history.undo(&mut self.bytes)
73 }
74
75 pub fn redo(&mut self) -> Option<&Change> {
78 self.history.redo(&mut self.bytes)
79 }
80
81 pub fn clear_history(&mut self) {
82 self.history.clear();
83 }
84
85 pub fn len(&self) -> usize {
86 self.bytes.len()
87 }
88
89 pub fn is_empty(&self) -> bool {
90 self.bytes.is_empty()
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn test_data_push_change() {
100 let mut data = Data::new(vec![0, 1, 2, 3, 4], 0);
101 assert_eq!(data.push_change(2, vec![9, 8, 7]), 3);
102 assert_eq!(data.bytes(), &[0, 1, 9, 8, 7]);
103 assert_eq!(data.push_change(2, vec![9, 8, 7]), 0);
104 assert_eq!(data.bytes(), &[0, 1, 9, 8, 7]);
105 assert_eq!(data.push_change(2, vec![9, 8, 7, 6]), 0);
106 assert_eq!(data.bytes(), &[0, 1, 9, 8, 7]);
107 assert_eq!(data.push_change(2, vec![9, 8, 7, 6, 5]), 0);
108 assert_eq!(data.bytes(), &[0, 1, 9, 8, 7]);
109 assert_eq!(data.push_change(2, vec![9, 8]), 0);
110 assert_eq!(data.bytes(), &[0, 1, 9, 8, 7]);
111 assert_eq!(data.push_change(2, vec![9, 8, 7]), 0);
112 assert_eq!(data.bytes(), &[0, 1, 9, 8, 7]);
113 assert_eq!(data.push_change(1, vec![9, 8, 7, 6]), 4);
114 assert_eq!(data.bytes(), &[0, 9, 8, 7, 6]);
115 assert_eq!(data.push_change(1, vec![9, 8, 7, 6, 5]), 0);
116 assert_eq!(data.bytes(), &[0, 9, 8, 7, 6]);
117 assert_eq!(data.push_change(1, vec![1, 2, 3, 4, 5]), 4);
118 assert_eq!(data.bytes(), &[0, 1, 2, 3, 4]);
119 }
120
121 #[test]
122 #[should_panic]
123 fn test_data_push_change_out_of_bounds() {
124 let mut data = Data::new(vec![0, 1, 2, 3, 4], 0);
125 data.push_change(5, vec![9, 8, 7]);
126 }
127
128 #[test]
129 fn test_data_undo_redo() {
130 let mut data = Data::new(vec![0, 1, 2, 3, 4], 0);
131 data.push_change(2, vec![9, 8, 7]);
132 assert_eq!(data.bytes(), &[0, 1, 9, 8, 7]);
133 data.push_change(0, vec![9, 8]);
134 assert_eq!(data.bytes(), &[9, 8, 9, 8, 7]);
135 data.push_change(4, vec![9]);
136 assert_eq!(data.bytes(), &[9, 8, 9, 8, 9]);
137 data.undo();
138 assert_eq!(data.bytes(), &[9, 8, 9, 8, 7]);
139 data.undo();
140 assert_eq!(data.bytes(), &[0, 1, 9, 8, 7]);
141 data.redo();
142 assert_eq!(data.bytes(), &[9, 8, 9, 8, 7]);
143 data.redo();
144 assert_eq!(data.bytes(), &[9, 8, 9, 8, 9]);
145 }
146
147 #[test]
148 fn test_data_clear_history() {
149 let mut data = Data::new(vec![0, 1, 2, 3, 4], 0);
150 data.push_change(2, vec![9, 8, 7]);
151 data.push_change(0, vec![9, 8]);
152 data.push_change(4, vec![9]);
153 assert_eq!(data.bytes(), &[9, 8, 9, 8, 9]);
154 data.clear_history();
155 data.undo();
156 assert_eq!(data.bytes(), &[9, 8, 9, 8, 9]);
157 }
158}