1use std::ops::{Mul, Range};
9
10use num_traits::Unsigned;
11
12#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub struct Span<Idx: Unsigned + Copy> {
15 pub start: Idx,
17
18 pub len: Idx,
20}
21
22impl<Idx: Unsigned + Copy> Span<Idx> {
23 #[inline]
25 pub fn end(&self) -> Idx {
26 self.start + self.len
27 }
28
29 #[inline]
31 pub fn range(self) -> Range<Idx> {
32 let Self { start, len } = self;
33 Range {
34 start,
35 end: start + len,
36 }
37 }
38
39 pub fn try_cast<Narrow>(self) -> Option<Span<Narrow>>
40 where
41 Narrow: TryFrom<Idx> + Unsigned + Copy,
42 {
43 Some(Span {
44 start: self.start.try_into().ok()?,
45 len: self.len.try_into().ok()?,
46 })
47 }
48}
49
50impl Span<u32> {
51 #[inline]
53 pub fn range_usize(self) -> Range<usize> {
54 let Self { start, len } = self;
55 Range {
56 start: start as usize,
57 end: start as usize + len as usize,
58 }
59 }
60}
61
62impl<Idx: Unsigned + Copy> From<Span<Idx>> for Range<Idx> {
63 #[inline]
64 fn from(value: Span<Idx>) -> Self {
65 value.range()
66 }
67}
68
69impl<Idx: Unsigned + Copy + Mul> Mul<Idx> for Span<Idx> {
71 type Output = Self;
72
73 fn mul(self, rhs: Idx) -> Self::Output {
74 let Self { start, len } = self;
75 Self {
76 start: rhs * start,
77 len: rhs * len,
78 }
79 }
80}