Skip to content
File

Blob: firmware/vendor/str0m/src/bwe/time.rs

rust761 lines
1use std::cmp::Ordering;
2use std::fmt;
3use std::ops::{Add, AddAssign, Div, Neg as _, Sub, SubAssign};
4use std::time::{Duration, Instant};
5 
6use crate::bwe::Bitrate;
7use crate::rtp_::DataSize;
8 
9/// Wrapper for [`Instant`] that provides additional time points in the past or future.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub(super) enum Timestamp {
12 /// A time in the past that already happened.
13 DistantPast,
14 
15 /// An exact instant.
16 Exact(Instant),
17 
18 /// A time in the future that will never happen.
19 DistantFuture,
20}
21 
22/// Wrapper for [`Duration`] that can be negative and provides a duration to a
23/// distant future or past.
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub(super) enum TimeDelta {
26 /// Time delta to some event in distant past that already happened.
27 NegativeInfinity,
28 
29 /// An exact negative duration.
30 Negative(Duration),
31 
32 /// An exact positive duration.
33 Positive(Duration),
34 
35 /// Time delta to some event in distant future that will never happen.
36 PositiveInfinity,
37}
38 
39impl TimeDelta {
40 pub(super) const ZERO: Self = Self::Positive(Duration::ZERO);
41 
42 /// Returns the number of seconds contained by this [`TimeDelta`] as `f64`.
43 pub fn as_secs_f64(&self) -> f64 {
44 match self {
45 Self::NegativeInfinity => f64::NEG_INFINITY,
46 Self::Negative(d) => d.as_secs_f64().neg(),
47 Self::Positive(d) => d.as_secs_f64(),
48 Self::PositiveInfinity => f64::INFINITY,
49 }
50 }
51}
52 
53#[cfg(test)]
54impl TimeDelta {
55 /// Creates a [`TimeDelta`] from seconds.
56 pub const fn from_secs(secs: i64) -> TimeDelta {
57 if secs >= 0 {
58 Self::Positive(Duration::from_secs(secs as u64))
59 } else {
60 Self::Negative(Duration::from_secs(-secs as u64))
61 }
62 }
63 
64 /// Creates a [`TimeDelta`] from milliseconds.
65 pub const fn from_millis(millis: i64) -> Self {
66 if millis >= 0 {
67 Self::Positive(Duration::from_millis(millis as u64))
68 } else {
69 Self::Negative(Duration::from_millis(-millis as u64))
70 }
71 }
72}
73 
74impl Timestamp {
75 /// Indicates whether this [`Timestamp`] is [`Timestamp::Exact`].
76 pub const fn is_exact(&self) -> bool {
77 matches!(self, Self::Exact(_))
78 }
79}
80 
81impl Add<TimeDelta> for Timestamp {
82 type Output = Self;
83 
84 fn add(self, rhs: TimeDelta) -> Self::Output {
85 match (self, rhs) {
86 (Self::DistantFuture, _) | (_, TimeDelta::PositiveInfinity) => Self::DistantFuture,
87 (Self::DistantPast, _) | (_, TimeDelta::NegativeInfinity) => Self::DistantPast,
88 (Self::Exact(i), TimeDelta::Negative(d)) => Self::Exact(i - d),
89 (Self::Exact(i), TimeDelta::Positive(d)) => Self::Exact(i + d),
90 }
91 }
92}
93 
94impl Sub<TimeDelta> for Timestamp {
95 type Output = Self;
96 
97 fn sub(self, rhs: TimeDelta) -> Self::Output {
98 match (self, rhs) {
99 (Self::DistantFuture, _) | (_, TimeDelta::NegativeInfinity) => Self::DistantFuture,
100 (Self::DistantPast, _) | (_, TimeDelta::PositiveInfinity) => Self::DistantPast,
101 (Self::Exact(i), TimeDelta::Negative(d)) => Self::Exact(i + d),
102 (Self::Exact(i), TimeDelta::Positive(d)) => Self::Exact(i - d),
103 }
104 }
105}
106 
107impl Sub<Self> for Timestamp {
108 type Output = TimeDelta;
109 
110 fn sub(self, rhs: Self) -> Self::Output {
111 match (self, rhs) {
112 (Self::DistantFuture, _) | (_, Self::DistantPast) => TimeDelta::PositiveInfinity,
113 (Self::DistantPast, _) | (_, Self::DistantFuture) => TimeDelta::NegativeInfinity,
114 (Self::Exact(this), Self::Exact(that)) => match this.cmp(&that) {
115 Ordering::Less => TimeDelta::Negative(that - this),
116 Ordering::Equal => TimeDelta::ZERO,
117 Ordering::Greater => TimeDelta::Positive(this - that),
118 },
119 }
120 }
121}
122 
123impl Add<Duration> for Timestamp {
124 type Output = Self;
125 
126 fn add(self, rhs: Duration) -> Self::Output {
127 self + TimeDelta::from(rhs)
128 }
129}
130 
131impl Sub<Duration> for Timestamp {
132 type Output = Self;
133 
134 fn sub(self, rhs: Duration) -> Self::Output {
135 self - TimeDelta::from(rhs)
136 }
137}
138 
139impl Sub<Instant> for Timestamp {
140 type Output = TimeDelta;
141 
142 fn sub(self, rhs: Instant) -> Self::Output {
143 self.sub(Self::from(rhs))
144 }
145}
146 
147impl SubAssign<TimeDelta> for Timestamp {
148 fn sub_assign(&mut self, rhs: TimeDelta) {
149 *self = *self - rhs;
150 }
151}
152 
153impl AddAssign<TimeDelta> for Timestamp {
154 fn add_assign(&mut self, rhs: TimeDelta) {
155 *self = *self + rhs;
156 }
157}
158 
159impl SubAssign<Duration> for Timestamp {
160 fn sub_assign(&mut self, rhs: Duration) {
161 *self = *self - rhs;
162 }
163}
164 
165impl AddAssign<Duration> for Timestamp {
166 fn add_assign(&mut self, rhs: Duration) {
167 *self = *self + rhs;
168 }
169}
170 
171impl PartialOrd for Timestamp {
172 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
173 Some(Self::cmp(self, other))
174 }
175}
176 
177impl Ord for Timestamp {
178 fn cmp(&self, other: &Self) -> Ordering {
179 match (self, other) {
180 (Self::DistantPast, Self::DistantPast) => Ordering::Equal,
181 (Self::DistantPast, _) => Ordering::Less,
182 (_, Self::DistantPast) => Ordering::Greater,
183 (Self::DistantFuture, Self::DistantFuture) => Ordering::Equal,
184 (Self::DistantFuture, _) => Ordering::Greater,
185 (_, Self::DistantFuture) => Ordering::Less,
186 (Self::Exact(v1), Self::Exact(v2)) => v1.cmp(v2),
187 }
188 }
189}
190 
191impl From<Instant> for Timestamp {
192 fn from(value: Instant) -> Self {
193 Self::Exact(value)
194 }
195}
196 
197impl Add<Self> for TimeDelta {
198 type Output = Self;
199 
200 fn add(self, rhs: Self) -> Self::Output {
201 match (self, rhs) {
202 (Self::PositiveInfinity, _) | (_, Self::PositiveInfinity) => Self::PositiveInfinity,
203 (Self::NegativeInfinity, _) | (_, Self::NegativeInfinity) => Self::NegativeInfinity,
204 (Self::Negative(this), Self::Negative(that)) => Self::Negative(this + that),
205 (Self::Positive(this), Self::Positive(that)) => Self::Positive(this + that),
206 (Self::Positive(this), Self::Negative(that)) => match this.cmp(&that) {
207 Ordering::Less => Self::Negative(that - this),
208 Ordering::Equal => Self::ZERO,
209 Ordering::Greater => Self::Positive(this - that),
210 },
211 (Self::Negative(this), Self::Positive(that)) => match this.cmp(&that) {
212 Ordering::Less => Self::Positive(that - this),
213 Ordering::Equal => Self::ZERO,
214 Ordering::Greater => Self::Negative(this - that),
215 },
216 }
217 }
218}
219 
220impl Sub<Self> for TimeDelta {
221 type Output = Self;
222 
223 fn sub(self, rhs: Self) -> Self::Output {
224 match (self, rhs) {
225 (Self::PositiveInfinity, _) | (_, Self::NegativeInfinity) => Self::PositiveInfinity,
226 (Self::NegativeInfinity, _) | (_, Self::PositiveInfinity) => Self::NegativeInfinity,
227 (Self::Positive(this), Self::Negative(that)) => Self::Positive(this + that),
228 (Self::Negative(this), Self::Positive(that)) => Self::Negative(this + that),
229 (Self::Positive(this), Self::Positive(that)) => match this.cmp(&that) {
230 Ordering::Less => Self::Negative(that - this),
231 Ordering::Equal => Self::ZERO,
232 Ordering::Greater => Self::Positive(this - that),
233 },
234 (Self::Negative(this), Self::Negative(that)) => match this.cmp(&that) {
235 Ordering::Less => Self::Positive(that - this),
236 Ordering::Equal => Self::ZERO,
237 Ordering::Greater => Self::Negative(this - that),
238 },
239 }
240 }
241}
242 
243impl PartialOrd for TimeDelta {
244 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
245 Some(Self::cmp(self, other))
246 }
247}
248 
249impl Ord for TimeDelta {
250 fn cmp(&self, other: &Self) -> Ordering {
251 match (self, other) {
252 (Self::NegativeInfinity, Self::NegativeInfinity) => Ordering::Equal,
253 (Self::NegativeInfinity, _) => Ordering::Less,
254 (_, Self::NegativeInfinity) => Ordering::Greater,
255 (Self::PositiveInfinity, Self::PositiveInfinity) => Ordering::Equal,
256 (Self::PositiveInfinity, _) => Ordering::Greater,
257 (_, Self::PositiveInfinity) => Ordering::Less,
258 (Self::Negative(_), Self::Positive(_)) => Ordering::Less,
259 (Self::Positive(_), Self::Negative(_)) => Ordering::Greater,
260 (Self::Positive(this), Self::Positive(that)) => this.cmp(that),
261 (Self::Negative(this), Self::Negative(that)) => that.cmp(this),
262 }
263 }
264}
265 
266impl PartialEq<Duration> for TimeDelta {
267 fn eq(&self, other: &Duration) -> bool {
268 *self == Self::from(*other)
269 }
270}
271 
272impl PartialOrd<Duration> for TimeDelta {
273 fn partial_cmp(&self, other: &Duration) -> Option<Ordering> {
274 Some(Self::cmp(self, &Self::from(*other)))
275 }
276}
277 
278impl SubAssign<Self> for TimeDelta {
279 fn sub_assign(&mut self, rhs: Self) {
280 *self = *self - rhs;
281 }
282}
283 
284impl AddAssign<Self> for TimeDelta {
285 fn add_assign(&mut self, rhs: Self) {
286 *self = *self + rhs;
287 }
288}
289 
290impl Div<u32> for TimeDelta {
291 type Output = Self;
292 
293 #[inline]
294 fn div(self, rhs: u32) -> Self {
295 match self {
296 Self::NegativeInfinity | Self::PositiveInfinity => self,
297 Self::Negative(duration) => Self::Negative(duration / rhs),
298 Self::Positive(duration) => Self::Positive(duration / rhs),
299 }
300 }
301}
302 
303impl From<Duration> for TimeDelta {
304 fn from(value: Duration) -> Self {
305 Self::Positive(value)
306 }
307}
308 
309impl Div<TimeDelta> for DataSize {
310 type Output = Bitrate;
311 
312 fn div(self, rhs: TimeDelta) -> Self::Output {
313 let bytes = self.as_bytes_f64();
314 let s = rhs.as_secs_f64();
315 
316 if s == 0.0 {
317 return Bitrate::ZERO;
318 }
319 
320 let bps = (bytes * 8.0) / s;
321 
322 bps.into()
323 }
324}
325 
326impl fmt::Display for TimeDelta {
327 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
328 match self {
329 TimeDelta::NegativeInfinity => write!(f, "-Inf"),
330 TimeDelta::Negative(v) => write!(f, "-{:.03}", v.as_secs_f32()),
331 TimeDelta::Positive(v) => write!(f, "{:.03}", v.as_secs_f32()),
332 TimeDelta::PositiveInfinity => write!(f, "+Inf"),
333 }
334 }
335}
336 
337#[cfg(test)]
338mod test {
339 use super::*;
340 
341 #[test]
342 fn instant_add_duration() {
343 let now = Instant::now();
344 
345 assert_eq!(
346 Timestamp::Exact(now) + TimeDelta::from_secs(5),
347 Timestamp::from(now + Duration::from_secs(5))
348 );
349 assert_eq!(
350 Timestamp::Exact(now) + TimeDelta::from_secs(-5),
351 Timestamp::from(now - Duration::from_secs(5))
352 );
353 assert_eq!(
354 Timestamp::Exact(now) + TimeDelta::NegativeInfinity,
355 Timestamp::DistantPast
356 );
357 assert_eq!(
358 Timestamp::Exact(now) + TimeDelta::PositiveInfinity,
359 Timestamp::DistantFuture
360 );
361 
362 assert_eq!(
363 Timestamp::DistantPast + TimeDelta::from_secs(5),
364 Timestamp::DistantPast
365 );
366 assert_eq!(
367 Timestamp::DistantPast + TimeDelta::from_secs(-5),
368 Timestamp::DistantPast
369 );
370 assert_eq!(
371 Timestamp::DistantPast + TimeDelta::NegativeInfinity,
372 Timestamp::DistantPast
373 );
374 assert_eq!(
375 Timestamp::DistantPast + TimeDelta::PositiveInfinity,
376 Timestamp::DistantFuture
377 );
378 
379 assert_eq!(
380 Timestamp::DistantFuture + TimeDelta::from_secs(5),
381 Timestamp::DistantFuture
382 );
383 assert_eq!(
384 Timestamp::DistantFuture + TimeDelta::from_secs(-5),
385 Timestamp::DistantFuture
386 );
387 assert_eq!(
388 Timestamp::DistantFuture + TimeDelta::NegativeInfinity,
389 Timestamp::DistantFuture
390 );
391 assert_eq!(
392 Timestamp::DistantFuture + TimeDelta::PositiveInfinity,
393 Timestamp::DistantFuture
394 );
395 }
396 
397 #[test]
398 fn instant_sub_duration() {
399 let now = Instant::now();
400 
401 assert_eq!(
402 Timestamp::Exact(now) - TimeDelta::from_secs(5),
403 Timestamp::from(now - Duration::from_secs(5))
404 );
405 assert_eq!(
406 Timestamp::Exact(now) - TimeDelta::from_secs(-5),
407 Timestamp::from(now + Duration::from_secs(5))
408 );
409 assert_eq!(
410 Timestamp::Exact(now) - TimeDelta::NegativeInfinity,
411 Timestamp::DistantFuture
412 );
413 assert_eq!(
414 Timestamp::Exact(now) - TimeDelta::PositiveInfinity,
415 Timestamp::DistantPast
416 );
417 
418 assert_eq!(
419 Timestamp::DistantPast - TimeDelta::from_secs(5),
420 Timestamp::DistantPast
421 );
422 assert_eq!(
423 Timestamp::DistantPast - TimeDelta::from_secs(-5),
424 Timestamp::DistantPast
425 );
426 assert_eq!(
427 Timestamp::DistantPast - TimeDelta::NegativeInfinity,
428 Timestamp::DistantFuture
429 );
430 assert_eq!(
431 Timestamp::DistantPast - TimeDelta::PositiveInfinity,
432 Timestamp::DistantPast
433 );
434 
435 assert_eq!(
436 Timestamp::DistantFuture - TimeDelta::from_secs(5),
437 Timestamp::DistantFuture
438 );
439 assert_eq!(
440 Timestamp::DistantFuture - TimeDelta::from_secs(-5),
441 Timestamp::DistantFuture
442 );
443 assert_eq!(
444 Timestamp::DistantFuture - TimeDelta::NegativeInfinity,
445 Timestamp::DistantFuture
446 );
447 assert_eq!(
448 Timestamp::DistantFuture - TimeDelta::PositiveInfinity,
449 Timestamp::DistantFuture
450 );
451 }
452 
453 #[test]
454 fn instant_sub_instant() {
455 let now = Instant::now();
456 
457 assert_eq!(
458 Timestamp::Exact(now) - Timestamp::Exact(now),
459 TimeDelta::ZERO
460 );
461 assert_eq!(
462 Timestamp::Exact(now) - Timestamp::Exact(now - Duration::from_secs(5)),
463 TimeDelta::from_secs(5)
464 );
465 assert_eq!(
466 Timestamp::Exact(now) - Timestamp::Exact(now + Duration::from_secs(5)),
467 TimeDelta::from_secs(-5)
468 );
469 assert_eq!(
470 Timestamp::Exact(now) - Timestamp::DistantPast,
471 TimeDelta::PositiveInfinity
472 );
473 assert_eq!(
474 Timestamp::Exact(now) - Timestamp::DistantFuture,
475 TimeDelta::NegativeInfinity
476 );
477 
478 assert_eq!(
479 Timestamp::DistantPast - Timestamp::Exact(now),
480 TimeDelta::NegativeInfinity
481 );
482 assert_eq!(
483 Timestamp::DistantPast - Timestamp::Exact(now - Duration::from_secs(5)),
484 TimeDelta::NegativeInfinity
485 );
486 assert_eq!(
487 Timestamp::DistantPast - Timestamp::Exact(now + Duration::from_secs(5)),
488 TimeDelta::NegativeInfinity
489 );
490 assert_eq!(
491 Timestamp::DistantPast - Timestamp::DistantPast,
492 TimeDelta::PositiveInfinity
493 );
494 assert_eq!(
495 Timestamp::DistantPast - Timestamp::DistantFuture,
496 TimeDelta::NegativeInfinity
497 );
498 
499 assert_eq!(
500 Timestamp::DistantFuture - Timestamp::Exact(now),
501 TimeDelta::PositiveInfinity
502 );
503 assert_eq!(
504 Timestamp::DistantFuture - Timestamp::Exact(now - Duration::from_secs(5)),
505 TimeDelta::PositiveInfinity
506 );
507 assert_eq!(
508 Timestamp::DistantFuture - Timestamp::Exact(now + Duration::from_secs(5)),
509 TimeDelta::PositiveInfinity
510 );
511 assert_eq!(
512 Timestamp::DistantFuture - Timestamp::DistantPast,
513 TimeDelta::PositiveInfinity
514 );
515 assert_eq!(
516 Timestamp::DistantFuture - Timestamp::DistantFuture,
517 TimeDelta::PositiveInfinity
518 );
519 }
520 
521 #[test]
522 fn instant_ord() {
523 let now = Timestamp::Exact(Instant::now());
524 let now_minus_1 = now - TimeDelta::from_secs(1);
525 let now_plus_1 = now + TimeDelta::from_secs(1);
526 
527 assert!(Timestamp::DistantFuture > now_plus_1);
528 assert!(Timestamp::DistantFuture > now_minus_1);
529 assert!(Timestamp::DistantFuture > Timestamp::DistantPast);
530 
531 assert!(now_plus_1 > now_minus_1);
532 assert!(now_plus_1 > Timestamp::DistantPast);
533 
534 assert!(now_minus_1 > Timestamp::DistantPast);
535 }
536 
537 #[test]
538 fn duration_ord() {
539 assert!(TimeDelta::PositiveInfinity > TimeDelta::from_secs(-2));
540 assert!(TimeDelta::PositiveInfinity > TimeDelta::from_secs(2));
541 assert!(TimeDelta::PositiveInfinity > TimeDelta::NegativeInfinity);
542 
543 assert!(TimeDelta::from_secs(2) > TimeDelta::from_secs(1));
544 assert!(TimeDelta::from_secs(2) > TimeDelta::from_secs(-1));
545 assert!(TimeDelta::from_secs(2) > TimeDelta::from_secs(-2));
546 assert!(TimeDelta::from_secs(2) > TimeDelta::NegativeInfinity);
547 
548 assert!(TimeDelta::from_secs(1) > TimeDelta::from_secs(-1));
549 assert!(TimeDelta::from_secs(1) > TimeDelta::from_secs(-2));
550 assert!(TimeDelta::from_secs(1) > TimeDelta::NegativeInfinity);
551 
552 assert!(TimeDelta::from_secs(-1) > TimeDelta::from_secs(-2));
553 assert!(TimeDelta::from_secs(-1) > TimeDelta::NegativeInfinity);
554 
555 assert!(TimeDelta::from_secs(-2) > TimeDelta::NegativeInfinity);
556 
557 assert_eq!(TimeDelta::from_secs(1), Duration::from_secs(1));
558 assert!(TimeDelta::from_secs(2) > Duration::from_secs(1));
559 assert!(TimeDelta::from_secs(1) < Duration::from_secs(2));
560 assert!(TimeDelta::from_secs(-1) < Duration::ZERO);
561 assert!(TimeDelta::from_secs(-1) < Duration::from_secs(1));
562 assert!(TimeDelta::PositiveInfinity > Duration::from_secs(2));
563 assert!(TimeDelta::NegativeInfinity < Duration::from_secs(1));
564 assert!(TimeDelta::NegativeInfinity < Duration::ZERO);
565 }
566 
567 #[test]
568 fn duration_add() {
569 assert_eq!(
570 TimeDelta::PositiveInfinity + TimeDelta::PositiveInfinity,
571 TimeDelta::PositiveInfinity
572 );
573 assert_eq!(
574 TimeDelta::PositiveInfinity + TimeDelta::NegativeInfinity,
575 TimeDelta::PositiveInfinity
576 );
577 assert_eq!(
578 TimeDelta::PositiveInfinity + TimeDelta::from_secs(-2),
579 TimeDelta::PositiveInfinity
580 );
581 assert_eq!(
582 TimeDelta::PositiveInfinity + TimeDelta::from_secs(2),
583 TimeDelta::PositiveInfinity
584 );
585 
586 assert_eq!(
587 TimeDelta::NegativeInfinity + TimeDelta::PositiveInfinity,
588 TimeDelta::PositiveInfinity
589 );
590 assert_eq!(
591 TimeDelta::NegativeInfinity + TimeDelta::NegativeInfinity,
592 TimeDelta::NegativeInfinity
593 );
594 assert_eq!(
595 TimeDelta::NegativeInfinity + TimeDelta::from_secs(-2),
596 TimeDelta::NegativeInfinity
597 );
598 assert_eq!(
599 TimeDelta::NegativeInfinity + TimeDelta::from_secs(2),
600 TimeDelta::NegativeInfinity
601 );
602 
603 assert_eq!(
604 TimeDelta::from_secs(1) + TimeDelta::PositiveInfinity,
605 TimeDelta::PositiveInfinity
606 );
607 assert_eq!(
608 TimeDelta::from_secs(1) + TimeDelta::NegativeInfinity,
609 TimeDelta::NegativeInfinity
610 );
611 assert_eq!(
612 TimeDelta::from_secs(1) + TimeDelta::from_secs(-1),
613 TimeDelta::ZERO
614 );
615 assert_eq!(
616 TimeDelta::from_secs(1) + TimeDelta::from_secs(-2),
617 TimeDelta::from_secs(-1)
618 );
619 assert_eq!(
620 TimeDelta::from_secs(1) + TimeDelta::from_secs(2),
621 TimeDelta::from_secs(3)
622 );
623 
624 assert_eq!(
625 TimeDelta::from_secs(-1) + TimeDelta::PositiveInfinity,
626 TimeDelta::PositiveInfinity
627 );
628 assert_eq!(
629 TimeDelta::from_secs(-1) + TimeDelta::NegativeInfinity,
630 TimeDelta::NegativeInfinity
631 );
632 assert_eq!(
633 TimeDelta::from_secs(-1) + TimeDelta::from_secs(1),
634 TimeDelta::ZERO
635 );
636 assert_eq!(
637 TimeDelta::from_secs(-1) + TimeDelta::from_secs(-2),
638 TimeDelta::from_secs(-3)
639 );
640 assert_eq!(
641 TimeDelta::from_secs(-1) + TimeDelta::from_secs(2),
642 TimeDelta::from_secs(1)
643 );
644 }
645 
646 #[test]
647 fn duration_sub() {
648 assert_eq!(
649 TimeDelta::PositiveInfinity - TimeDelta::PositiveInfinity,
650 TimeDelta::PositiveInfinity
651 );
652 assert_eq!(
653 TimeDelta::PositiveInfinity - TimeDelta::NegativeInfinity,
654 TimeDelta::PositiveInfinity
655 );
656 assert_eq!(
657 TimeDelta::PositiveInfinity - TimeDelta::from_secs(-2),
658 TimeDelta::PositiveInfinity
659 );
660 assert_eq!(
661 TimeDelta::PositiveInfinity - TimeDelta::from_secs(2),
662 TimeDelta::PositiveInfinity
663 );
664 
665 assert_eq!(
666 TimeDelta::NegativeInfinity - TimeDelta::NegativeInfinity,
667 TimeDelta::PositiveInfinity
668 );
669 assert_eq!(
670 TimeDelta::NegativeInfinity - TimeDelta::PositiveInfinity,
671 TimeDelta::NegativeInfinity
672 );
673 assert_eq!(
674 TimeDelta::NegativeInfinity - TimeDelta::from_secs(-2),
675 TimeDelta::NegativeInfinity
676 );
677 assert_eq!(
678 TimeDelta::NegativeInfinity - TimeDelta::from_secs(2),
679 TimeDelta::NegativeInfinity
680 );
681 
682 assert_eq!(
683 TimeDelta::from_secs(1) - TimeDelta::NegativeInfinity,
684 TimeDelta::PositiveInfinity
685 );
686 assert_eq!(
687 TimeDelta::from_secs(1) - TimeDelta::PositiveInfinity,
688 TimeDelta::NegativeInfinity
689 );
690 assert_eq!(
691 TimeDelta::from_secs(1) - TimeDelta::from_secs(1),
692 TimeDelta::ZERO
693 );
694 assert_eq!(
695 TimeDelta::from_secs(1) - TimeDelta::from_secs(-1),
696 TimeDelta::from_secs(2)
697 );
698 assert_eq!(
699 TimeDelta::from_secs(1) - TimeDelta::from_secs(2),
700 TimeDelta::from_secs(-1)
701 );
702 
703 assert_eq!(
704 TimeDelta::from_secs(-1) - TimeDelta::NegativeInfinity,
705 TimeDelta::PositiveInfinity
706 );
707 assert_eq!(
708 TimeDelta::from_secs(-1) - TimeDelta::PositiveInfinity,
709 TimeDelta::NegativeInfinity
710 );
711 assert_eq!(
712 TimeDelta::from_secs(-1) - TimeDelta::from_secs(-1),
713 TimeDelta::ZERO
714 );
715 assert_eq!(
716 TimeDelta::from_secs(-1) - TimeDelta::from_secs(1),
717 TimeDelta::from_secs(-2)
718 );
719 assert_eq!(
720 TimeDelta::from_secs(-1) - TimeDelta::from_secs(2),
721 TimeDelta::from_secs(-3)
722 );
723 }
724 
725 #[test]
726 fn super_instant_test() {
727 let mut past = Timestamp::DistantPast;
728 let mut future = Timestamp::DistantFuture;
729 let now = Timestamp::Exact(Instant::now());
730 assert!(past < now);
731 assert!(now > past);
732 
733 assert!(now < future);
734 assert!(future > now);
735 
736 assert!(past < future);
737 assert!(future > past);
738 
739 assert!(now == now);
740 assert!(past == past);
741 assert!(future == future);
742 
743 assert!(now != past);
744 assert!(now != future);
745 assert!(future != past);
746 
747 assert!(past - Duration::from_secs(1) == past);
748 past -= Duration::from_secs(1);
749 assert!(past == past);
750 past += Duration::from_secs(1);
751 assert!(past == past);
752 
753 assert!(future + Duration::from_secs(1) == future);
754 assert!(future - Duration::from_secs(1) == future);
755 future -= Duration::from_secs(1);
756 assert!(future == future);
757 future += Duration::from_secs(1);
758 assert!(future == future);
759 }
760}