cola/
utils.rs

1use core::fmt::{Debug, Formatter, Result as FmtResult};
2use core::ops::{Add, Range as StdRange, RangeBounds, Sub};
3
4use crate::Length;
5
6#[derive(Clone, Copy, PartialEq, Eq, Hash)]
7pub(crate) struct Range<T> {
8    pub start: T,
9    pub end: T,
10}
11
12impl<T: Debug> Debug for Range<T> {
13    fn fmt(&self, f: &mut Formatter) -> FmtResult {
14        write!(f, "{:?}..{:?}", self.start, self.end)
15    }
16}
17
18impl<T> From<StdRange<T>> for Range<T> {
19    #[inline]
20    fn from(range: StdRange<T>) -> Self {
21        Range { start: range.start, end: range.end }
22    }
23}
24
25impl<T> From<Range<T>> for StdRange<T> {
26    #[inline]
27    fn from(range: Range<T>) -> Self {
28        StdRange { start: range.start, end: range.end }
29    }
30}
31
32impl<T: Sub<T, Output = T> + Copy> Sub<T> for Range<T> {
33    type Output = Range<T>;
34
35    #[inline]
36    fn sub(self, value: T) -> Self::Output {
37        Range { start: self.start - value, end: self.end - value }
38    }
39}
40
41impl<T: Add<T, Output = T> + Copy> Add<T> for Range<T> {
42    type Output = Range<T>;
43
44    #[inline]
45    fn add(self, value: T) -> Self::Output {
46        Range { start: self.start + value, end: self.end + value }
47    }
48}
49
50impl<T> Range<T> {
51    #[inline]
52    pub fn len(&self) -> T
53    where
54        T: Sub<T, Output = T> + Copy,
55    {
56        self.end - self.start
57    }
58}
59
60pub(crate) trait RangeExt<T> {
61    fn contains_range(&self, range: Range<T>) -> bool;
62}
63
64impl<T: Ord> RangeExt<T> for StdRange<T> {
65    #[inline]
66    fn contains_range(&self, other: Range<T>) -> bool {
67        self.start <= other.start && self.end >= other.end
68    }
69}
70
71/// TODO: docs
72#[inline]
73pub(crate) fn get_two_mut<T>(
74    slice: &mut [T],
75    first_idx: usize,
76    second_idx: usize,
77) -> (&mut T, &mut T) {
78    debug_assert!(first_idx != second_idx);
79
80    if first_idx < second_idx {
81        debug_assert!(second_idx < slice.len());
82        let split_at = first_idx + 1;
83        let (first, second) = slice.split_at_mut(split_at);
84        (&mut first[first_idx], &mut second[second_idx - split_at])
85    } else {
86        debug_assert!(first_idx < slice.len());
87        let split_at = second_idx + 1;
88        let (first, second) = slice.split_at_mut(split_at);
89        (&mut second[first_idx - split_at], &mut first[second_idx])
90    }
91}
92
93/// TODO: docs
94#[inline]
95pub(crate) fn insert_in_slice<T>(slice: &mut [T], elem: T, at_offset: usize) {
96    debug_assert!(at_offset < slice.len());
97    slice[at_offset..].rotate_right(1);
98    slice[at_offset] = elem;
99}
100
101/// TODO: docs
102#[inline(always)]
103pub(crate) fn range_bounds_to_start_end<R>(
104    range: R,
105    lo: Length,
106    hi: Length,
107) -> (Length, Length)
108where
109    R: RangeBounds<Length>,
110{
111    use core::ops::Bound;
112
113    let start = match range.start_bound() {
114        Bound::Included(&n) => n,
115        Bound::Excluded(&n) => n + 1,
116        Bound::Unbounded => lo,
117    };
118
119    let end = match range.end_bound() {
120        Bound::Included(&n) => n + 1,
121        Bound::Excluded(&n) => n,
122        Bound::Unbounded => hi,
123    };
124
125    (start, end)
126}
127
128pub mod panic_messages {
129    use crate::Length;
130
131    #[track_caller]
132    #[cold]
133    #[inline(never)]
134    pub(crate) fn offset_out_of_bounds(offset: Length, len: Length) -> ! {
135        debug_assert!(offset > len);
136        panic!(
137            "offset out of bounds: the offset is {offset} but the length is \
138             {len}"
139        );
140    }
141
142    #[track_caller]
143    #[cold]
144    #[inline(never)]
145    pub(crate) fn replica_id_equal_to_forked() -> ! {
146        panic!(
147            "invalid ReplicaId: must not be equal to the one of the forked \
148             Replica, consider cloning instead"
149        );
150    }
151
152    #[track_caller]
153    #[cold]
154    #[inline(never)]
155    pub(crate) fn replica_id_is_zero() -> ! {
156        panic!("invalid ReplicaId: must not be zero");
157    }
158
159    #[track_caller]
160    #[cold]
161    #[inline(never)]
162    pub(crate) fn start_greater_than_end(start: Length, end: Length) -> ! {
163        debug_assert!(start > end);
164        panic!(
165            "offset range's start is greater than its end: the start is \
166             {start} but the end is {end}"
167        );
168    }
169}