imbl/
util.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5// Every codebase needs a `util` module.
6
7use std::ops::{Bound, Range, RangeBounds};
8
9use archery::{SharedPointer, SharedPointerKind};
10
11pub(crate) fn clone_ref<A, P>(r: SharedPointer<A, P>) -> A
12where
13    A: Clone,
14    P: SharedPointerKind,
15{
16    SharedPointer::try_unwrap(r).unwrap_or_else(|r| (*r).clone())
17}
18
19#[derive(Clone, Copy, PartialEq, Eq, Debug)]
20pub(crate) enum Side {
21    Left,
22    Right,
23}
24
25pub(crate) fn to_range<R>(range: &R, right_unbounded: usize) -> Range<usize>
26where
27    R: RangeBounds<usize>,
28{
29    let start_index = match range.start_bound() {
30        Bound::Included(i) => *i,
31        Bound::Excluded(i) => *i + 1,
32        Bound::Unbounded => 0,
33    };
34    let end_index = match range.end_bound() {
35        Bound::Included(i) => *i + 1,
36        Bound::Excluded(i) => *i,
37        Bound::Unbounded => right_unbounded,
38    };
39    start_index..end_index
40}
41
42#[cfg(test)]
43macro_rules! assert_covariant {
44    ($name:ident<$($gen:tt),*> in $param:ident) => {
45        #[allow(dead_code, unused_assignments, unused_variables)]
46        const _: () = {
47            type Tmp<$param> = $name<$($gen),*>;
48            fn assign<'a, 'b: 'a>(src: Tmp<&'b i32>, mut dst: Tmp<&'a i32>) {
49                dst = src;
50            }
51        };
52    }
53}