term_model/grid/
row.rs
1use std::cmp::{max, min};
18use std::ops::{Index, IndexMut};
19use std::ops::{Range, RangeFrom, RangeFull, RangeTo, RangeToInclusive};
20use std::slice;
21
22use serde::{Deserialize, Serialize};
23
24use crate::grid::GridCell;
25use crate::index::Column;
26
27#[derive(Default, Clone, Debug, Serialize, Deserialize)]
29pub struct Row<T> {
30 inner: Vec<T>,
31
32 pub(crate) occ: usize,
37}
38
39impl<T: PartialEq> PartialEq for Row<T> {
40 fn eq(&self, other: &Self) -> bool {
41 self.inner == other.inner
42 }
43}
44
45impl<T: Copy> Row<T> {
46 pub fn new(columns: Column, template: &T) -> Row<T>
47 where
48 T: GridCell,
49 {
50 let occ = if template.is_empty() { 0 } else { columns.0 };
51 Row { inner: vec![*template; columns.0], occ }
52 }
53
54 pub fn grow(&mut self, cols: Column, template: &T) {
55 if self.inner.len() >= cols.0 {
56 return;
57 }
58
59 self.inner.append(&mut vec![*template; cols.0 - self.len()]);
60 }
61
62 pub fn shrink(&mut self, cols: Column) -> Option<Vec<T>>
63 where
64 T: GridCell,
65 {
66 if self.inner.len() <= cols.0 {
67 return None;
68 }
69
70 let mut new_row = self.inner.split_off(cols.0);
72 let index = new_row.iter().rposition(|c| !c.is_empty()).map(|i| i + 1).unwrap_or(0);
73 new_row.truncate(index);
74
75 self.occ = min(self.occ, cols.0);
76
77 if new_row.is_empty() {
78 None
79 } else {
80 Some(new_row)
81 }
82 }
83
84 #[inline]
86 pub fn reset(&mut self, template: &T)
87 where
88 T: GridCell + PartialEq,
89 {
90 debug_assert!(!self.inner.is_empty());
91
92 let template = *template;
93
94 let len = self.inner.len();
96 if !self.inner[len - 1].fast_eq(template) {
97 self.occ = len;
98 }
99
100 for item in &mut self.inner[..self.occ] {
103 *item = template;
104 }
105
106 self.occ = 0;
107 }
108}
109
110#[allow(clippy::len_without_is_empty)]
111impl<T> Row<T> {
112 #[inline]
113 pub fn from_vec(vec: Vec<T>, occ: usize) -> Row<T> {
114 Row { inner: vec, occ }
115 }
116
117 #[inline]
118 pub fn len(&self) -> usize {
119 self.inner.len()
120 }
121
122 #[inline]
123 pub fn last(&self) -> Option<&T> {
124 self.inner.last()
125 }
126
127 #[inline]
128 pub fn last_mut(&mut self) -> Option<&mut T> {
129 self.occ = self.inner.len();
130 self.inner.last_mut()
131 }
132
133 #[inline]
134 pub fn append(&mut self, vec: &mut Vec<T>)
135 where
136 T: GridCell,
137 {
138 self.occ += vec.len();
139 self.inner.append(vec);
140 }
141
142 #[inline]
143 pub fn append_front(&mut self, mut vec: Vec<T>) {
144 self.occ += vec.len();
145
146 vec.append(&mut self.inner);
147 self.inner = vec;
148 }
149
150 #[inline]
151 pub fn is_empty(&self) -> bool
152 where
153 T: GridCell,
154 {
155 self.inner.iter().all(GridCell::is_empty)
156 }
157
158 #[inline]
159 pub fn front_split_off(&mut self, at: usize) -> Vec<T> {
160 self.occ = self.occ.saturating_sub(at);
161
162 let mut split = self.inner.split_off(at);
163 std::mem::swap(&mut split, &mut self.inner);
164 split
165 }
166}
167
168impl<'a, T> IntoIterator for &'a mut Row<T> {
169 type IntoIter = slice::IterMut<'a, T>;
170 type Item = &'a mut T;
171
172 #[inline]
173 fn into_iter(self) -> slice::IterMut<'a, T> {
174 self.occ = self.len();
175 self.inner.iter_mut()
176 }
177}
178
179impl<T> Index<Column> for Row<T> {
180 type Output = T;
181
182 #[inline]
183 fn index(&self, index: Column) -> &T {
184 &self.inner[index.0]
185 }
186}
187
188impl<T> IndexMut<Column> for Row<T> {
189 #[inline]
190 fn index_mut(&mut self, index: Column) -> &mut T {
191 self.occ = max(self.occ, *index + 1);
192 &mut self.inner[index.0]
193 }
194}
195
196impl<T> Index<Range<Column>> for Row<T> {
201 type Output = [T];
202
203 #[inline]
204 fn index(&self, index: Range<Column>) -> &[T] {
205 &self.inner[(index.start.0)..(index.end.0)]
206 }
207}
208
209impl<T> IndexMut<Range<Column>> for Row<T> {
210 #[inline]
211 fn index_mut(&mut self, index: Range<Column>) -> &mut [T] {
212 self.occ = max(self.occ, *index.end);
213 &mut self.inner[(index.start.0)..(index.end.0)]
214 }
215}
216
217impl<T> Index<RangeTo<Column>> for Row<T> {
218 type Output = [T];
219
220 #[inline]
221 fn index(&self, index: RangeTo<Column>) -> &[T] {
222 &self.inner[..(index.end.0)]
223 }
224}
225
226impl<T> IndexMut<RangeTo<Column>> for Row<T> {
227 #[inline]
228 fn index_mut(&mut self, index: RangeTo<Column>) -> &mut [T] {
229 self.occ = max(self.occ, *index.end);
230 &mut self.inner[..(index.end.0)]
231 }
232}
233
234impl<T> Index<RangeFrom<Column>> for Row<T> {
235 type Output = [T];
236
237 #[inline]
238 fn index(&self, index: RangeFrom<Column>) -> &[T] {
239 &self.inner[(index.start.0)..]
240 }
241}
242
243impl<T> IndexMut<RangeFrom<Column>> for Row<T> {
244 #[inline]
245 fn index_mut(&mut self, index: RangeFrom<Column>) -> &mut [T] {
246 self.occ = self.len();
247 &mut self.inner[(index.start.0)..]
248 }
249}
250
251impl<T> Index<RangeFull> for Row<T> {
252 type Output = [T];
253
254 #[inline]
255 fn index(&self, _: RangeFull) -> &[T] {
256 &self.inner[..]
257 }
258}
259
260impl<T> IndexMut<RangeFull> for Row<T> {
261 #[inline]
262 fn index_mut(&mut self, _: RangeFull) -> &mut [T] {
263 self.occ = self.len();
264 &mut self.inner[..]
265 }
266}
267
268impl<T> Index<RangeToInclusive<Column>> for Row<T> {
269 type Output = [T];
270
271 #[inline]
272 fn index(&self, index: RangeToInclusive<Column>) -> &[T] {
273 &self.inner[..=(index.end.0)]
274 }
275}
276
277impl<T> IndexMut<RangeToInclusive<Column>> for Row<T> {
278 #[inline]
279 fn index_mut(&mut self, index: RangeToInclusive<Column>) -> &mut [T] {
280 self.occ = max(self.occ, *index.end);
281 &mut self.inner[..=(index.end.0)]
282 }
283}