solar_interface/
pos.rs

1use std::{
2    fmt,
3    ops::{Add, AddAssign, Sub, SubAssign},
4};
5
6macro_rules! impl_pos {
7    (
8        $(
9            $(#[$attr:meta])*
10            $vis:vis struct $ident:ident($inner_vis:vis $inner_ty:ty);
11        )*
12    ) => {
13        $(
14            $(#[$attr])*
15            $vis struct $ident($inner_vis $inner_ty);
16
17            impl fmt::Debug for $ident {
18                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19                    write!(f, "{}({})", stringify!($ident), self.0)
20                }
21            }
22
23            impl $ident {
24                #[inline(always)]
25                pub fn from_u32(n: u32) -> Self {
26                    Self(n as $inner_ty)
27                }
28
29                #[inline(always)]
30                pub fn from_usize(n: usize) -> Self {
31                    Self(n as $inner_ty)
32                }
33
34                #[inline(always)]
35                pub fn to_u32(self) -> u32 {
36                    self.0 as u32
37                }
38
39                #[inline(always)]
40                pub fn to_usize(self) -> usize {
41                    self.0 as usize
42                }
43            }
44
45            impl Add for $ident {
46                type Output = Self;
47
48                #[inline(always)]
49                fn add(self, rhs: Self) -> Self {
50                    Self(self.0 + rhs.0)
51                }
52            }
53
54            impl Add<$inner_ty> for $ident {
55                type Output = Self;
56
57                #[inline(always)]
58                fn add(self, rhs: $inner_ty) -> Self {
59                    Self(self.0 + rhs)
60                }
61            }
62
63            impl AddAssign for $ident {
64                #[inline(always)]
65                fn add_assign(&mut self, rhs: Self) {
66                    *self = Self(self.0 + rhs.0);
67                }
68            }
69
70            impl AddAssign<$inner_ty> for $ident {
71                #[inline(always)]
72                fn add_assign(&mut self, rhs: $inner_ty) {
73                    self.0 += rhs;
74                }
75            }
76
77            impl Sub for $ident {
78                type Output = Self;
79
80                #[inline(always)]
81                fn sub(self, rhs: Self) -> Self {
82                    Self(self.0 - rhs.0)
83                }
84            }
85
86            impl Sub<$inner_ty> for $ident {
87                type Output = Self;
88
89                #[inline(always)]
90                fn sub(self, rhs: $inner_ty) -> Self {
91                    Self(self.0 - rhs)
92                }
93            }
94
95            impl SubAssign for $ident {
96                #[inline(always)]
97                fn sub_assign(&mut self, rhs: Self) {
98                    *self = *self - rhs;
99                }
100            }
101
102            impl SubAssign<$inner_ty> for $ident {
103                #[inline(always)]
104                fn sub_assign(&mut self, rhs: $inner_ty) {
105                    self.0 -= rhs;
106                }
107            }
108        )*
109    };
110}
111
112impl_pos! {
113    /// A byte offset relative to the global source map.
114    ///
115    /// Keep this small (currently 32-bits), as AST contains a lot of them.
116    #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
117    pub struct BytePos(pub u32);
118
119    /// A byte offset relative to file beginning.
120    #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
121    pub struct RelativeBytePos(pub u32);
122
123    /// A character offset.
124    ///
125    /// Because of multibyte UTF-8 characters, a byte offset
126    /// is not equivalent to a character offset. The [`SourceMap`](crate::SourceMap) will convert
127    /// [`BytePos`] values to `CharPos` values as necessary.
128    #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
129    pub struct CharPos(pub usize);
130}