1use std::ops::{Deref, DerefMut, Range};
2
3pub trait HasLength {
4 fn len(&self) -> usize;
6
7 #[inline]
8 fn is_empty(&self) -> bool {
9 self.len() == 0
10 }
11}
12
13impl<V> HasLength for &V where V: HasLength {
14 fn len(&self) -> usize { (*self).len() }
15}
16
17pub trait SplitableSpanHelpers: Clone {
18 fn truncate_h(&mut self, at: usize) -> Self;
29
30 #[inline(always)]
33 fn truncate_keeping_right_h(&mut self, at: usize) -> Self {
34 let mut other = self.clone();
35 *self = other.truncate_h(at);
36 other
37 }
38
39 fn split(mut self, at: usize) -> (Self, Self) {
40 let remainder = self.truncate_h(at);
41 (self, remainder)
42 }
43}
44
45impl<T: SplitableSpanHelpers> SplitableSpanCtx for T {
46 type Ctx = ();
47
48 fn truncate_ctx(&mut self, at: usize, _ctx: &Self::Ctx) -> Self {
49 self.truncate_h(at)
50 }
53}
54
55pub trait SplitableSpanCtx: Clone {
56 type Ctx: ?Sized;
57
58 fn truncate_ctx(&mut self, at: usize, ctx: &Self::Ctx) -> Self;
69
70 #[inline(always)]
73 fn truncate_keeping_right_ctx(&mut self, at: usize, ctx: &Self::Ctx) -> Self {
74 let mut other = self.clone();
75 *self = other.truncate_ctx(at, ctx);
76 other
77 }
78
79 fn split_ctx(mut self, at: usize, ctx: &Self::Ctx) -> (Self, Self) {
80 let remainder = self.truncate_ctx(at, ctx);
81 (self, remainder)
82 }
83}
84
85pub trait SplitableSpan: SplitableSpanCtx<Ctx=()> {
87 fn truncate(&mut self, at: usize) -> Self {
98 self.truncate_ctx(at, &())
99 }
100
101 #[inline(always)]
104 fn truncate_keeping_right(&mut self, at: usize) -> Self {
105 self.truncate_keeping_right_ctx(at, &())
106 }
107
108 fn split_h(mut self, at: usize) -> (Self, Self) {
109 let remainder = self.truncate_ctx(at, &());
110 (self, remainder)
111 }
112}
113
114impl<T: SplitableSpanCtx<Ctx=()>> SplitableSpan for T {}
115
116#[derive(Debug)]
119pub struct WithCtx<'a, T: SplitableSpanCtx + Clone>(pub T, pub &'a T::Ctx);
120
121impl<'a, T: SplitableSpanCtx + Clone> Deref for WithCtx<'a, T> {
122 type Target = T;
123
124 fn deref(&self) -> &Self::Target {
125 &self.0
126 }
127}
128
129impl<'a, T: SplitableSpanCtx + Clone> DerefMut for WithCtx<'a, T> {
130 fn deref_mut(&mut self) -> &mut Self::Target {
131 &mut self.0
132 }
133}
134
135impl<'a, T: SplitableSpanCtx + Clone> WithCtx<'a, T> {
136 pub fn new(t: T, ctx: &'a T::Ctx) -> Self {
137 Self(t, ctx)
138 }
139
140 pub fn to_inner(self) -> T {
141 self.0
142 }
143}
144
145impl<'a, T: SplitableSpanCtx + Clone> Clone for WithCtx<'a, T> {
146 fn clone(&self) -> Self {
147 WithCtx(self.0.clone(), self.1)
148 }
149}
150
151impl<'a, T: SplitableSpanCtx> SplitableSpanCtx for WithCtx<'a, T> {
152 type Ctx = ();
153
154 fn truncate_ctx(&mut self, at: usize, _ctx: &Self::Ctx) -> Self {
155 WithCtx(self.0.truncate_ctx(at, self.1), self.1)
156 }
157
158 fn truncate_keeping_right_ctx(&mut self, at: usize, _ctx: &Self::Ctx) -> Self {
159 WithCtx(self.0.truncate_keeping_right_ctx(at, self.1), self.1)
160 }
161}
162
163impl<'a, T: SplitableSpanCtx + HasLength> HasLength for WithCtx<'a, T> {
164 fn len(&self) -> usize {
165 self.0.len()
166 }
167}
168
169pub trait TrimCtx: SplitableSpanCtx + HasLength {
187 #[inline]
189 fn trim_ctx(&mut self, at: usize, ctx: &Self::Ctx) -> Option<Self> {
190 if at >= self.len() {
191 None
192 } else {
193 Some(self.truncate_ctx(at, ctx))
194 }
195 }
196}
197
198impl<T: SplitableSpanCtx + HasLength> TrimCtx for T {}
199
200pub trait Trim: SplitableSpan + HasLength {
201 #[inline]
202 fn trim(&mut self, at: usize) -> Option<Self> {
203 self.trim_ctx(at, &())
204 }
205}
206
207impl<T: SplitableSpan + HasLength> Trim for T {}
208
209
210pub struct Shatter<T>(Option<T>);
212
213impl<T: SplitableSpan + HasLength> Iterator for Shatter<T> {
214 type Item = T;
215
216 fn next(&mut self) -> Option<Self::Item> {
217 let Some(val) = self.0.as_mut() else { return None; };
218
219 if val.len() > 1 {
220 Some(val.truncate_keeping_right(1))
221 } else {
222 self.0.take()
223 }
224 }
225}
226
227pub fn shatter<T: SplitableSpan + HasLength>(item: T) -> Shatter<T> {
229 Shatter(Some(item))
230}
231
232pub trait MergableSpan: Clone {
233 fn can_append(&self, other: &Self) -> bool;
236
237 fn append(&mut self, other: Self);
242
243 #[inline(always)]
248 fn prepend(&mut self, mut other: Self) {
249 other.append(self.clone());
250 *self = other;
251 }
252}
253
254pub trait SplitAndJoinSpan: HasLength + SplitableSpan + MergableSpan {}
259impl<T: HasLength + SplitableSpan + MergableSpan> SplitAndJoinSpan for T {}
260
261pub trait SplitAndJoinSpanCtx: HasLength + SplitableSpanCtx + MergableSpan {}
262impl<T: HasLength + SplitableSpanCtx + MergableSpan> SplitAndJoinSpanCtx for T {}
263
264#[derive(Copy, Clone, Hash, Debug, PartialEq, Eq, Default)]
266pub struct Single<T>(pub T);
267
268#[derive(Copy, Clone, Hash, Debug, PartialEq, Eq, Default)]
270pub struct ReverseSpan<S>(pub S);
271
272impl<T> HasLength for Single<T> {
273 fn len(&self) -> usize { 1 }
274}
275impl<T: Clone> SplitableSpanHelpers for Single<T> {
276 fn truncate_h(&mut self, _at: usize) -> Self { panic!("Cannot truncate single sized item"); }
278}
279impl<T: Clone> MergableSpan for Single<T> {
280 fn can_append(&self, _other: &Self) -> bool { false }
281 fn append(&mut self, _other: Self) { panic!("Cannot append to single sized item"); }
282}
283
284impl<S: HasLength> HasLength for ReverseSpan<S> {
291 fn len(&self) -> usize { self.0.len() }
292}
293impl<S: SplitableSpanCtx<Ctx=()>> SplitableSpanHelpers for ReverseSpan<S> {
294 fn truncate_h(&mut self, at: usize) -> Self {
295 ReverseSpan(self.0.truncate_keeping_right(at))
296 }
297 fn truncate_keeping_right_h(&mut self, at: usize) -> Self {
298 ReverseSpan(self.0.truncate(at))
299 }
300}
301impl<S: MergableSpan> MergableSpan for ReverseSpan<S> {
302 fn can_append(&self, other: &Self) -> bool { other.0.can_append(&self.0) }
303 fn append(&mut self, other: Self) { self.0.prepend(other.0); }
304 fn prepend(&mut self, other: Self) { self.0.append(other.0); }
305}
306
307impl<A, B> MergableSpan for (A, B) where A: MergableSpan, B: MergableSpan {
308 fn can_append(&self, other: &Self) -> bool {
309 self.0.can_append(&other.0) && self.1.can_append(&other.1)
310 }
311
312 fn append(&mut self, other: Self) {
313 self.0.append(other.0);
314 self.1.append(other.1);
315 }
316}
317
318impl<A, B> HasLength for (A, B) where A: HasLength {
319 fn len(&self) -> usize {
320 self.0.len()
322 }
323}
324
325impl<A, B> SplitableSpanHelpers for (A, B) where A: SplitableSpan, B: SplitableSpan {
326 fn truncate_h(&mut self, at: usize) -> Self {
327 (self.0.truncate(at), self.1.truncate(at))
328 }
329}
330
331impl<T, E> SplitableSpanCtx for Result<T, E> where T: SplitableSpanCtx + Clone, E: Clone {
350 type Ctx = T::Ctx;
351
352 fn truncate_ctx(&mut self, at: usize, ctx: &Self::Ctx) -> Self {
353 match self {
354 Ok(v) => Result::Ok(v.truncate_ctx(at, ctx)),
355 Err(e) => Result::Err(e.clone())
356 }
357 }
358}
359
360impl<T, E> HasLength for Result<T, E> where T: HasLength, Result<T, E>: Clone {
361 fn len(&self) -> usize {
362 match self {
363 Ok(val) => val.len(),
364 Err(_) => 1
365 }
366 }
367}
368
369impl<V> SplitableSpanHelpers for Option<V> where V: SplitableSpan {
370 fn truncate_h(&mut self, at: usize) -> Self {
371 self.as_mut().map(|v| v.truncate(at))
372 }
377}
378
379impl HasLength for Range<u32> {
404 fn len(&self) -> usize { (self.end - self.start) as _ }
405}
406impl SplitableSpanHelpers for Range<u32> {
411 fn truncate_h(&mut self, at: usize) -> Self {
413 let old_end = self.end;
414 self.end = self.start + at as u32;
415 Self { start: self.end, end: old_end }
416 }
417}
418impl MergableSpan for Range<u32> {
419 fn can_append(&self, other: &Self) -> bool {
420 self.end == other.start
421 }
422
423 fn append(&mut self, other: Self) {
424 self.end = other.end;
425 }
426}
427
428impl SplitableSpanHelpers for Range<usize> {
429 fn truncate_h(&mut self, at: usize) -> Self {
431 let old_end = self.end;
432 self.end = self.start + at;
433 Self { start: self.end, end: old_end }
434 }
435}
436impl MergableSpan for Range<usize> {
437 fn can_append(&self, other: &Self) -> bool {
438 self.end == other.start
439 }
440
441 fn append(&mut self, other: Self) {
442 self.end = other.end;
443 }
444}
445
446pub fn test_splitable_methods_valid<E: SplitAndJoinSpan + std::fmt::Debug + Clone + Eq>(entry: E) {
452 test_splitable_methods_valid_ctx(entry, &());
453}
454
455pub fn test_splitable_methods_valid_ctx<E: SplitAndJoinSpanCtx + std::fmt::Debug + Clone + Eq>(entry: E, ctx: &E::Ctx) {
456 assert!(entry.len() >= 2, "Call this with a larger entry");
457 for i in 1..entry.len() {
460 let mut start = entry.clone();
462 let end = start.truncate_ctx(i, ctx);
463 assert_eq!(start.len(), i);
466 assert_eq!(end.len(), entry.len() - i);
467
468 assert!(start.can_append(&end));
470
471 let mut merge_append = start.clone();
472
473 merge_append.append(end.clone());
475 assert_eq!(merge_append, entry);
477
478 let mut merge_prepend = end.clone();
479 merge_prepend.prepend(start.clone());
480 assert_eq!(merge_prepend, entry);
481
482 let mut end2 = entry.clone();
484 let start2 = end2.truncate_keeping_right_ctx(i, ctx);
485 assert_eq!(end2, end);
486 assert_eq!(start2, start);
487 }
488}
489
490#[cfg(test)]
491mod test {
492 use crate::vendor::rle::*;
493 use crate::vendor::rle::rlerun::{RleDRun, RleRun};
494
495 #[test]
496 fn test_rle_run() {
497 assert!(!RleRun { val: 10, len: 5 }.can_append(&RleRun { val: 20, len: 5 }));
498 assert!(RleRun { val: 10, len: 5 }.can_append(&RleRun { val: 10, len: 15 }));
499
500 test_splitable_methods_valid(RleRun { val: 12, len: 5 });
501 }
502
503 #[test]
504 fn test_rle_distinct() {
505 assert!(RleDRun::new(0..10, 'x').can_append(&RleDRun::new(10..20, 'x')));
506 assert!(!RleDRun::new(0..10, 'x').can_append(&RleDRun::new(10..20, 'y')));
507 assert!(!RleDRun::new(0..10, 'x').can_append(&RleDRun::new(11..20, 'x')));
508
509 test_splitable_methods_valid(RleDRun::new(0..10, 'x'));
510 }
511
512 #[test]
513 fn splitable_range() {
514 test_splitable_methods_valid(0..10);
515 test_splitable_methods_valid(0u32..10u32);
516 }
517}