miden_diagnostics/
index.rs1use std::num::NonZeroUsize;
2use std::ops::{Add, AddAssign, Sub, SubAssign};
3
4use codespan::{ByteIndex, ByteOffset, RawIndex, RawOffset};
5
6use super::SourceId;
7
8#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub struct SourceIndex(NonZeroUsize);
13impl SourceIndex {
14 const INDEX_MASK: usize = u32::max_value() as usize;
15
16 const UNKNOWN_SRC_ID: usize = (SourceId::UNKNOWN_SOURCE_ID as usize) << 32;
17
18 pub const UNKNOWN: Self = Self(unsafe { NonZeroUsize::new_unchecked(Self::UNKNOWN_SRC_ID) });
20
21 #[inline]
23 pub fn new(source: SourceId, index: ByteIndex) -> Self {
24 let source = (source.get() as usize) << 32;
25
26 Self(NonZeroUsize::new(source | index.0 as usize).unwrap())
27 }
28
29 #[inline]
31 pub fn source_id(&self) -> SourceId {
32 let source_id_part = (self.0.get() >> 32) as u32;
33 if source_id_part == SourceId::UNKNOWN_SOURCE_ID {
34 SourceId::UNKNOWN
35 } else {
36 SourceId::new(source_id_part)
37 }
38 }
39
40 #[inline]
42 pub fn index(&self) -> ByteIndex {
43 ByteIndex((self.0.get() & Self::INDEX_MASK) as u32)
44 }
45
46 #[doc(hidden)]
47 pub fn to_usize(&self) -> usize {
48 self.0.get()
49 }
50}
51impl Default for SourceIndex {
52 fn default() -> Self {
53 Self::UNKNOWN
54 }
55}
56
57impl Add<usize> for SourceIndex {
58 type Output = SourceIndex;
59
60 #[inline]
61 fn add(self, rhs: usize) -> Self {
62 if self == Self::UNKNOWN {
63 return Self::UNKNOWN;
64 }
65 let source = self.source_id();
66 let index = self.index();
67 let new_index = index.0 as RawOffset + rhs as RawOffset;
68 Self::new(source, ByteIndex(new_index as RawIndex))
69 }
70}
71
72impl Add<ByteOffset> for SourceIndex {
73 type Output = SourceIndex;
74
75 #[inline]
76 fn add(self, rhs: ByteOffset) -> Self {
77 if self == Self::UNKNOWN {
78 return Self::UNKNOWN;
79 }
80 let source = self.source_id();
81 let index = self.index();
82 let new_index = ByteIndex(index.0) + rhs;
83 Self::new(source, new_index)
84 }
85}
86
87impl AddAssign<usize> for SourceIndex {
88 #[inline]
89 fn add_assign(&mut self, rhs: usize) {
90 *self = *self + rhs;
91 }
92}
93
94impl AddAssign<ByteOffset> for SourceIndex {
95 #[inline]
96 fn add_assign(&mut self, rhs: ByteOffset) {
97 *self = *self + rhs;
98 }
99}
100
101impl Sub<usize> for SourceIndex {
102 type Output = SourceIndex;
103
104 #[inline]
105 fn sub(self, rhs: usize) -> Self {
106 if self == Self::UNKNOWN {
107 return Self::UNKNOWN;
108 }
109 let source = self.source_id();
110 let index = self.index();
111 let new_index = index.0 as RawOffset - rhs as RawOffset;
112 Self::new(source, ByteIndex(new_index as RawIndex))
113 }
114}
115
116impl SubAssign<usize> for SourceIndex {
117 #[inline]
118 fn sub_assign(&mut self, rhs: usize) {
119 *self = *self - rhs;
120 }
121}