1use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
18use std::convert::From;
19use std::ops::{Add, Sub};
20
21use tracing::{Span, instrument};
22
23use crate::Result;
24use crate::error::HyperlightError;
25
26#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
30pub(crate) struct Offset(u64);
31
32impl Default for Offset {
33 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
34 fn default() -> Self {
35 Offset::from(0_u64)
36 }
37}
38
39impl From<u64> for Offset {
40 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
41 fn from(val: u64) -> Self {
42 Self(val)
43 }
44}
45
46impl From<&Offset> for u64 {
47 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
48 fn from(val: &Offset) -> u64 {
49 val.0
50 }
51}
52
53impl From<Offset> for u64 {
54 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
55 fn from(val: Offset) -> u64 {
56 val.0
57 }
58}
59
60impl TryFrom<Offset> for i64 {
61 type Error = HyperlightError;
62 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
63 fn try_from(val: Offset) -> Result<i64> {
64 Ok(i64::try_from(val.0)?)
65 }
66}
67
68impl TryFrom<i64> for Offset {
69 type Error = HyperlightError;
70 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
71 fn try_from(val: i64) -> Result<Offset> {
72 let val_u64 = u64::try_from(val)?;
73 Ok(Offset::from(val_u64))
74 }
75}
76
77impl TryFrom<usize> for Offset {
78 type Error = HyperlightError;
79 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
80 fn try_from(val: usize) -> Result<Offset> {
81 Ok(u64::try_from(val).map(Offset::from)?)
82 }
83}
84
85impl TryFrom<&Offset> for usize {
88 type Error = HyperlightError;
89 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
90 fn try_from(val: &Offset) -> Result<usize> {
91 Ok(usize::try_from(val.0)?)
92 }
93}
94
95impl TryFrom<Offset> for usize {
96 type Error = HyperlightError;
97 #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
98 fn try_from(val: Offset) -> Result<usize> {
99 usize::try_from(&val)
100 }
101}
102
103impl Add<Offset> for Offset {
104 type Output = Offset;
105 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
106 fn add(self, rhs: Offset) -> Offset {
107 Offset::from(self.0 + rhs.0)
108 }
109}
110
111impl Add<usize> for Offset {
112 type Output = Offset;
113 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
114 fn add(self, rhs: usize) -> Offset {
115 Offset(self.0 + rhs as u64)
116 }
117}
118
119impl Add<Offset> for usize {
120 type Output = Offset;
121 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
122 fn add(self, rhs: Offset) -> Offset {
123 rhs.add(self)
124 }
125}
126
127impl Add<u64> for Offset {
128 type Output = Offset;
129 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
130 fn add(self, rhs: u64) -> Offset {
131 Offset(self.0 + rhs)
132 }
133}
134
135impl Add<Offset> for u64 {
136 type Output = Offset;
137 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
138 fn add(self, rhs: Offset) -> Offset {
139 rhs.add(self)
140 }
141}
142
143impl Sub<Offset> for Offset {
144 type Output = Offset;
145 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
146 fn sub(self, rhs: Offset) -> Offset {
147 Offset::from(self.0 - rhs.0)
148 }
149}
150
151impl Sub<usize> for Offset {
152 type Output = Offset;
153 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
154 fn sub(self, rhs: usize) -> Offset {
155 Offset(self.0 - rhs as u64)
156 }
157}
158
159impl Sub<Offset> for usize {
160 type Output = Offset;
161 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
162 fn sub(self, rhs: Offset) -> Offset {
163 rhs.sub(self)
164 }
165}
166
167impl Sub<u64> for Offset {
168 type Output = Offset;
169 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
170 fn sub(self, rhs: u64) -> Offset {
171 Offset(self.0 - rhs)
172 }
173}
174
175impl Sub<Offset> for u64 {
176 type Output = Offset;
177 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
178 fn sub(self, rhs: Offset) -> Offset {
179 rhs.sub(self)
180 }
181}
182
183impl PartialEq<usize> for Offset {
184 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
185 fn eq(&self, other: &usize) -> bool {
186 match usize::try_from(self) {
187 Ok(offset_usize) => offset_usize == *other,
188 _ => false,
189 }
190 }
191}
192
193impl PartialOrd<usize> for Offset {
194 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
195 fn partial_cmp(&self, rhs: &usize) -> Option<Ordering> {
196 match usize::try_from(self) {
197 Ok(offset_usize) if offset_usize > *rhs => Some(Ordering::Greater),
198 Ok(offset_usize) if offset_usize == *rhs => Some(Ordering::Equal),
199 Ok(_) => Some(Ordering::Less),
200 Err(_) => None,
201 }
202 }
203}
204
205impl PartialEq<u64> for Offset {
206 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
207 fn eq(&self, rhs: &u64) -> bool {
208 u64::from(self) == *rhs
209 }
210}
211
212impl PartialOrd<u64> for Offset {
213 #[instrument(skip_all, parent = Span::current(), level= "Trace")]
214 fn partial_cmp(&self, rhs: &u64) -> Option<Ordering> {
215 let lhs: u64 = self.into();
216 match lhs > *rhs {
217 true => Some(Ordering::Greater),
218 false if lhs == *rhs => Some(Ordering::Equal),
219 false => Some(Ordering::Less),
220 }
221 }
222}