1#![expect(deprecated)]
4
5use core::borrow::Borrow;
6use core::cmp::{Ord, Ordering, PartialEq, PartialOrd};
7use core::ops::{Add, Sub};
8use core::time::Duration as StdDuration;
9use std::time::Instant as StdInstant;
10
11use crate::internal_macros::{impl_add_assign, impl_sub_assign};
12use crate::Duration;
13
14#[doc(hidden)]
32#[deprecated(
33    since = "0.3.35",
34    note = "import `std::time::Instant` and `time::ext::InstantExt` instead"
35)]
36#[repr(transparent)]
37#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
38pub struct Instant(pub StdInstant);
39
40impl Instant {
41    #[inline]
49    pub fn now() -> Self {
50        Self(StdInstant::now())
51    }
52
53    #[inline]
65    pub fn elapsed(self) -> Duration {
66        Self::now() - self
67    }
68
69    #[inline]
81    pub fn checked_add(self, duration: Duration) -> Option<Self> {
82        if duration.is_zero() {
83            Some(self)
84        } else if duration.is_positive() {
85            self.0.checked_add(duration.unsigned_abs()).map(Self)
86        } else {
87            debug_assert!(duration.is_negative());
88            self.0.checked_sub(duration.unsigned_abs()).map(Self)
89        }
90    }
91
92    #[inline]
104    pub fn checked_sub(self, duration: Duration) -> Option<Self> {
105        if duration.is_zero() {
106            Some(self)
107        } else if duration.is_positive() {
108            self.0.checked_sub(duration.unsigned_abs()).map(Self)
109        } else {
110            debug_assert!(duration.is_negative());
111            self.0.checked_add(duration.unsigned_abs()).map(Self)
112        }
113    }
114
115    #[inline]
124    pub const fn into_inner(self) -> StdInstant {
125        self.0
126    }
127}
128
129impl From<StdInstant> for Instant {
130    #[inline]
131    fn from(instant: StdInstant) -> Self {
132        Self(instant)
133    }
134}
135
136impl From<Instant> for StdInstant {
137    #[inline]
138    fn from(instant: Instant) -> Self {
139        instant.0
140    }
141}
142
143impl Sub for Instant {
144    type Output = Duration;
145
146    #[inline]
150    fn sub(self, other: Self) -> Self::Output {
151        match self.0.cmp(&other.0) {
152            Ordering::Equal => Duration::ZERO,
153            Ordering::Greater => (self.0 - other.0)
154                .try_into()
155                .expect("overflow converting `std::time::Duration` to `time::Duration`"),
156            Ordering::Less => -Duration::try_from(other.0 - self.0)
157                .expect("overflow converting `std::time::Duration` to `time::Duration`"),
158        }
159    }
160}
161
162impl Sub<StdInstant> for Instant {
163    type Output = Duration;
164
165    #[inline]
166    fn sub(self, other: StdInstant) -> Self::Output {
167        self - Self(other)
168    }
169}
170
171impl Sub<Instant> for StdInstant {
172    type Output = Duration;
173
174    #[inline]
175    fn sub(self, other: Instant) -> Self::Output {
176        Instant(self) - other
177    }
178}
179
180impl Add<Duration> for Instant {
181    type Output = Self;
182
183    #[inline]
188    fn add(self, duration: Duration) -> Self::Output {
189        if duration.is_positive() {
190            Self(self.0 + duration.unsigned_abs())
191        } else if duration.is_negative() {
192            #[expect(clippy::unchecked_duration_subtraction)]
193            Self(self.0 - duration.unsigned_abs())
194        } else {
195            debug_assert!(duration.is_zero());
196            self
197        }
198    }
199}
200
201impl Add<Duration> for StdInstant {
202    type Output = Self;
203
204    #[inline]
205    fn add(self, duration: Duration) -> Self::Output {
206        (Instant(self) + duration).0
207    }
208}
209
210impl Add<StdDuration> for Instant {
211    type Output = Self;
212
213    #[inline]
214    fn add(self, duration: StdDuration) -> Self::Output {
215        Self(self.0 + duration)
216    }
217}
218
219impl_add_assign!(Instant: Duration, StdDuration);
220impl_add_assign!(StdInstant: Duration);
221
222impl Sub<Duration> for Instant {
223    type Output = Self;
224
225    #[inline]
230    fn sub(self, duration: Duration) -> Self::Output {
231        if duration.is_positive() {
232            #[expect(clippy::unchecked_duration_subtraction)]
233            Self(self.0 - duration.unsigned_abs())
234        } else if duration.is_negative() {
235            Self(self.0 + duration.unsigned_abs())
236        } else {
237            debug_assert!(duration.is_zero());
238            self
239        }
240    }
241}
242
243impl Sub<Duration> for StdInstant {
244    type Output = Self;
245
246    #[inline]
247    fn sub(self, duration: Duration) -> Self::Output {
248        (Instant(self) - duration).0
249    }
250}
251
252impl Sub<StdDuration> for Instant {
253    type Output = Self;
254
255    #[inline]
260    fn sub(self, duration: StdDuration) -> Self::Output {
261        #[expect(clippy::unchecked_duration_subtraction)]
262        Self(self.0 - duration)
263    }
264}
265
266impl_sub_assign!(Instant: Duration, StdDuration);
267impl_sub_assign!(StdInstant: Duration);
268
269impl PartialEq<StdInstant> for Instant {
270    #[inline]
271    fn eq(&self, rhs: &StdInstant) -> bool {
272        self.0.eq(rhs)
273    }
274}
275
276impl PartialEq<Instant> for StdInstant {
277    #[inline]
278    fn eq(&self, rhs: &Instant) -> bool {
279        self.eq(&rhs.0)
280    }
281}
282
283impl PartialOrd<StdInstant> for Instant {
284    #[inline]
285    fn partial_cmp(&self, rhs: &StdInstant) -> Option<Ordering> {
286        self.0.partial_cmp(rhs)
287    }
288}
289
290impl PartialOrd<Instant> for StdInstant {
291    #[inline]
292    fn partial_cmp(&self, rhs: &Instant) -> Option<Ordering> {
293        self.partial_cmp(&rhs.0)
294    }
295}
296
297impl AsRef<StdInstant> for Instant {
298    #[inline]
299    fn as_ref(&self) -> &StdInstant {
300        &self.0
301    }
302}
303
304impl Borrow<StdInstant> for Instant {
305    #[inline]
306    fn borrow(&self) -> &StdInstant {
307        &self.0
308    }
309}