1use std::{borrow::Cow, cmp::Ordering, fmt, io::{self}, ops, time::Duration};
17
18use chrono::{DateTime, TimeZone};
19use nix::libc::{self, ECANCELED, EWOULDBLOCK};
20use bitflags::bitflags;
21
22
23use crate::{common, timer_portable::portable_error::TimerPortResult};
24
25#[cfg(target_os = "linux")]
26pub use super::linux::timer_fd_linux::*;
27
28#[cfg(
29 all(
30 any(
31 target_os = "freebsd",
32 target_os = "dragonfly",
33 target_os = "netbsd",
34 target_os = "openbsd",
35 target_os = "macos",
36 ),
37 feature = "bsd_use_timerfd"
38 )
39)]
40pub use super::bsd::timer_fd_bsd::*;
41
42#[cfg(
43 all(
44 any(
45 target_os = "freebsd",
46 target_os = "dragonfly",
47 target_os = "netbsd",
48 target_os = "openbsd",
49 target_os = "macos",
50 ),
51 not(feature = "bsd_use_timerfd")
52 )
53)]
54pub use super::bsd::timer_kqueue_fd_bsd::*;
55
56#[cfg(
57 all(
58 any(
59 target_os = "freebsd",
60 target_os = "dragonfly",
61 target_os = "netbsd",
62 target_os = "openbsd",
63 target_os = "macos",
64 ),
65 not(feature = "bsd_use_timerfd")
66 )
67)]
68use super::portable_error::TimerPortableErr;
69
70
71#[allow(non_camel_case_types)]
73#[repr(i32)]
74#[derive(Debug)]
75pub enum TimerType
76{
77 CLOCK_REALTIME = libc::CLOCK_REALTIME,
79
80 CLOCK_MONOTONIC = libc::CLOCK_MONOTONIC,
85
86
87 #[cfg(target_os = "linux")]
95 CLOCK_BOOTTIME = libc::CLOCK_BOOTTIME,
96
97 #[cfg(target_os = "linux")]
101 CLOCK_REALTIME_ALARM = libc::CLOCK_REALTIME_ALARM,
102
103 #[cfg(target_os = "linux")]
107 CLOCK_BOOTTIME_ALARM = libc::CLOCK_BOOTTIME_ALARM,
108}
109
110impl From<TimerType> for libc::clockid_t
138{
139 fn from(value: TimerType) -> Self
140 {
141 return value as libc::clockid_t;
142 }
143}
144
145
146bitflags! {
147 #[derive(Default, Debug, Clone, Copy)]
149 pub struct TimerFlags: i32
150 {
151 const TFD_NONBLOCK = libc::TFD_NONBLOCK;
156
157 const TFD_CLOEXEC = libc::TFD_CLOEXEC;
161 }
162}
163
164
165bitflags! {
166 #[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
168 pub struct TimerSetTimeFlags: i32
169 {
170 const TFD_TIMER_ABSTIME = libc::TFD_TIMER_ABSTIME;
174
175 const TFD_TIMER_CANCEL_ON_SET = libc::TFD_TIMER_CANCEL_ON_SET;
183 }
184}
185
186
187pub trait ModeTimeType: Eq + PartialEq + Ord + PartialOrd + fmt::Display + fmt::Debug + Clone + Copy
195{
196
197 fn new(time_spec: timespec) -> Self where Self: Sized;
208
209 fn get_sec(&self) -> i64;
211
212 fn get_nsec(&self) -> i64;
214
215 fn is_value_valid(&self) -> bool;
217
218 fn get_flags() -> TimerSetTimeFlags;
221}
222
223#[derive(Debug, PartialEq, Eq, Clone, Copy)]
225pub struct RelativeTime
226{
227 time_sec: i64,
229
230 time_nsec: i64,
232}
233
234impl From<Duration> for RelativeTime
237{
238 fn from(value: Duration) -> Self
239 {
240 return Self
241 {
242 time_sec:
243 value.as_secs() as i64,
244 time_nsec:
245 value.subsec_nanos() as i64,
246 };
247 }
248}
249
250impl Ord for RelativeTime
251{
252 fn cmp(&self, other: &Self) -> Ordering
253 {
254 return
255 self
256 .time_sec
257 .cmp(&other.time_sec)
258 .then(
259 self
260 .time_nsec
261 .cmp(&other.time_nsec)
262 );
263 }
264}
265
266impl PartialOrd for RelativeTime
267{
268 fn partial_cmp(&self, other: &Self) -> Option<Ordering>
269 {
270 return Some(self.cmp(other));
271 }
272}
273
274impl fmt::Display for RelativeTime
275{
276 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
277 {
278 write!(f, "[relative] sec: {}, nsec: {}", self.time_sec, self.time_nsec)
279 }
280}
281
282impl ModeTimeType for RelativeTime
283{
284 fn new(time_spec: timespec) -> RelativeTime
285 {
286 return
287 Self::new_time(time_spec.tv_sec, time_spec.tv_nsec);
288 }
289
290 fn get_sec(&self) -> i64
291 {
292 return self.time_sec;
293 }
294
295 fn get_nsec(&self) -> i64 {
296
297 return self.time_nsec;
298 }
299
300 fn is_value_valid(&self) -> bool
301 {
302 return true;
303 }
304
305 fn get_flags() -> TimerSetTimeFlags
306 {
307 return TimerSetTimeFlags::empty();
308 }
309}
310
311impl RelativeTime
312{
313 pub const MAX_NS: i64 = 1_000_000_000;
315
316 pub
330 fn new_time(time_sec: i64, time_nsec: i64) -> Self
331 {
332 let extra_sec = time_nsec / Self::MAX_NS;
333 let nsec_new = time_nsec % Self::MAX_NS;
334
335 return
336 Self
337 {
338 time_nsec: nsec_new,
339 time_sec: time_sec + extra_sec,
340 };
341 }
342}
343
344#[derive(Debug, PartialEq, Eq, Clone, Copy)]
347pub struct AbsoluteTime
348{
349 time_sec: i64,
351
352 time_nsec: i64,
354}
355
356impl<TZ: TimeZone> From<DateTime<TZ>> for AbsoluteTime
360{
361 fn from(value: DateTime<TZ>) -> Self
362 {
363 return Self
364 {
365 time_sec:
366 value.timestamp(),
367 time_nsec:
368 value.timestamp_subsec_nanos() as i64,
369 };
370 }
371}
372
373impl From<Duration> for AbsoluteTime
376{
377 fn from(value: Duration) -> Self
378 {
379 return Self
380 {
381 time_sec:
382 value.as_secs() as i64,
383 time_nsec:
384 value.subsec_nanos() as i64,
385 };
386 }
387}
388
389impl Ord for AbsoluteTime
390{
391 fn cmp(&self, other: &Self) -> Ordering
392 {
393 return
394 self
395 .time_sec
396 .cmp(&other.time_sec)
397 .then(
398 self
399 .time_nsec
400 .cmp(&other.time_nsec)
401 );
402 }
403}
404
405impl PartialOrd for AbsoluteTime
406{
407 fn partial_cmp(&self, other: &Self) -> Option<Ordering>
408 {
409 return Some(self.cmp(other));
410 }
411}
412
413impl ops::AddAssign<RelativeTime> for AbsoluteTime
414{
415 fn add_assign(&mut self, rhs: RelativeTime)
416 {
417 self.time_nsec += rhs.time_nsec;
418 let add_sec = self.time_nsec / Self::MAX_NS;
419
420 if add_sec > 0
421 {
422 self.time_nsec %= Self::MAX_NS;
423 }
424
425 self.time_sec += rhs.time_sec + add_sec;
426 }
427}
428
429impl ops::Add<RelativeTime> for AbsoluteTime
430{
431 type Output = AbsoluteTime;
432
433 fn add(mut self, rhs: RelativeTime) -> Self::Output
434 {
435 self += rhs;
436
437 return self;
438 }
439}
440
441impl ops::SubAssign<RelativeTime> for AbsoluteTime
442{
443 fn sub_assign(&mut self, mut rhs: RelativeTime)
444 {
445
446 let mut nsec = self.time_nsec - rhs.time_nsec;
447
448 if nsec < 0
449 {
450 rhs.time_sec += 1;
451
452 nsec = Self::MAX_NS + nsec;
453 }
454
455 self.time_nsec = nsec;
456 self.time_sec -= rhs.time_sec;
457
458 return;
459 }
460}
461
462impl ops::Sub<RelativeTime> for AbsoluteTime
463{
464 type Output = AbsoluteTime;
465
466 fn sub(mut self, rhs: RelativeTime) -> Self::Output
467 {
468 self -= rhs;
469
470 return self;
471 }
472}
473
474impl ops::SubAssign for AbsoluteTime
475{
476 fn sub_assign(&mut self, mut rhs: Self)
477 {
478
479 let mut nsec = self.time_nsec - rhs.time_nsec;
480
481 if nsec < 0
482 {
483 rhs.time_sec += 1;
484
485 nsec = Self::MAX_NS + nsec;
486 }
487
488 self.time_nsec = nsec;
489 self.time_sec -= rhs.time_sec;
490
491 return;
492 }
493}
494
495impl ops::Sub for AbsoluteTime
496{
497 type Output = AbsoluteTime;
498
499 fn sub(mut self, rhs: Self) -> Self::Output
500 {
501 self -= rhs;
502
503 return self;
504 }
505}
506
507
508impl fmt::Display for AbsoluteTime
509{
510 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
511 {
512 write!(f, "[absolute] {}.{}sec", self.time_sec, self.time_nsec)
513 }
514}
515
516
517impl ModeTimeType for AbsoluteTime
518{
519 fn new(time_spec: timespec) -> Self where Self: Sized
520 {
521 return
522 unsafe { Self::new_time_unchecked(time_spec.tv_sec, time_spec.tv_nsec) };
523 }
524
525 fn get_sec(&self) -> i64
526 {
527 return self.time_sec;
528 }
529
530 fn get_nsec(&self) -> i64
531 {
532
533 return self.time_nsec;
534 }
535
536 fn is_value_valid(&self) -> bool
537 {
538 return self.time_nsec != 0 || self.time_sec != 0;
539 }
540
541 fn get_flags() -> TimerSetTimeFlags
542 {
543 return TimerSetTimeFlags::TFD_TIMER_ABSTIME | TimerSetTimeFlags::TFD_TIMER_CANCEL_ON_SET;
544 }
545}
546
547impl AbsoluteTime
548{
549 pub const MAX_NS: i64 = 1_000_000_000;}
552
553impl AbsoluteTime
554{
555 pub
557 fn now() -> Self
558 {
559 let value = common::get_current_timestamp();
560
561 return Self
562 {
563 time_sec: value.timestamp(),
564 time_nsec: value.timestamp_subsec_nanos() as i64,
565 }
566 }
567
568 pub
569 fn new_time(time_sec: i64, time_nsec: i64) -> Option<Self>
570 {
571 let tm =
572 unsafe { Self::new_time_unchecked(time_sec, time_nsec) };
573
574 if tm.is_value_valid() == false
575 {
576 return None;
577 }
578
579 return Some(tm);
580 }
581
582 pub unsafe
600 fn new_time_unchecked(time_sec: i64, time_nsec: i64) -> Self
601 {
602 let extra_sec = time_nsec / Self::MAX_NS;
603 let nsec_new = time_nsec % Self::MAX_NS;
604
605 return
606 Self
607 {
608 time_nsec: nsec_new,
609 time_sec: time_sec + extra_sec,
610 };
611 }
612
613 pub
615 fn seconds_cmp(&self, other: &Self) -> Ordering
616 {
617 return self.time_sec.cmp(&other.time_sec);
618 }
619
620 pub
621 fn add_sec(mut self, seconds: i64) -> Self
622 {
623 self.time_sec += seconds;
624
625 return self;
626 }
627
628 pub
629 fn reset_nsec(mut self) -> Self
630 {
631 self.time_nsec = 0;
632
633 return self;
634 }
635}
636
637
638
639#[derive(Clone, Copy, Debug, PartialEq, Eq)]
644pub enum TimerExpMode<TIMERTYPE: ModeTimeType>
645{
646 None,
648
649 OneShot
651 {
652 timeout: TIMERTYPE
653 },
654
655 IntervalDelayed
657 {
658 delay_tm: TIMERTYPE,
660
661 interv_tm: TIMERTYPE
663 },
664
665 Interval
668 {
669 interv_tm: TIMERTYPE
671 },
672}
673
674
675impl ops::AddAssign<RelativeTime> for TimerExpMode<AbsoluteTime>
676{
677 fn add_assign(&mut self, rhs: RelativeTime)
678 {
679 match self
680 {
681 TimerExpMode::None =>
682 return,
683 TimerExpMode::OneShot { timeout } =>
684 {
685 *timeout += rhs;
686
687 },
688 TimerExpMode::IntervalDelayed { interv_tm, .. } =>
689 {
690 *interv_tm += rhs;
691 },
692 TimerExpMode::Interval { interv_tm } =>
693 {
694 *interv_tm += rhs;
695 },
696 }
697 }
698}
699
700
701impl ops::Add<RelativeTime> for TimerExpMode<AbsoluteTime>
702{
703 type Output = TimerExpMode<AbsoluteTime>;
704
705 fn add(mut self, rhs: RelativeTime) -> Self::Output
706 {
707 self += rhs;
708
709 return self;
710 }
711}
712
713
714impl<TIMERTYPE: ModeTimeType> Ord for TimerExpMode<TIMERTYPE>
715{
716 fn cmp(&self, other: &Self) -> Ordering
717 {
718 match (self, other)
719 {
720 (TimerExpMode::None, TimerExpMode::None) =>
721 return Ordering::Equal,
722 (TimerExpMode::OneShot{ timeout }, TimerExpMode::OneShot { timeout: timeout2 }) =>
723 {
724 return timeout.cmp(timeout2);
725 },
726 (
727 TimerExpMode::IntervalDelayed{ delay_tm, interv_tm },
728 TimerExpMode::IntervalDelayed{ delay_tm: delay_tm2, interv_tm: interv_tm2 }
729 ) =>
730 {
731 return
732 delay_tm.cmp(delay_tm2)
733 .then(interv_tm.cmp(interv_tm2));
734 },
735 (TimerExpMode::Interval { interv_tm }, TimerExpMode::Interval { interv_tm: interv_tm2 }) =>
736 {
737 return interv_tm.cmp(interv_tm2);
738 },
739 _ =>
740 panic!("cannot compare different types {} and {}", self, other)
741 }
742 }
743}
744
745impl<TIMERTYPE: ModeTimeType> PartialOrd for TimerExpMode<TIMERTYPE>
746{
747 fn partial_cmp(&self, other: &Self) -> Option<Ordering>
748 {
749 return Some(self.cmp(other));
750 }
751}
752
753
754
755impl TimerExpMode<AbsoluteTime>
757{
758 #[inline]
761 fn is_valid_inner(&self) -> bool
762 {
763 match self
764 {
765 Self::None =>
766 return false,
767 Self::OneShot{ timeout} =>
768 return timeout.is_value_valid(),
769 Self::IntervalDelayed{ delay_tm, interv_tm } =>
770 return delay_tm.is_value_valid() && interv_tm.is_value_valid(),
771 Self::Interval{ interv_tm } =>
772 return interv_tm.is_value_valid()
773 }
774 }
775
776 pub
780 fn new_oneshot(abs_time: AbsoluteTime) -> Self
781 {
782 return Self::OneShot { timeout: abs_time };
783 }
784}
785
786
787
788impl TimerExpMode<RelativeTime>
790{
791 pub
794 fn new_oneshot(rel_time: RelativeTime) -> Self
795 {
796 return Self::OneShot { timeout: rel_time };
797 }
798
799 pub
802 fn new_interval(rel_time: RelativeTime) -> Self
803 {
804 return Self::Interval { interv_tm: rel_time };
805 }
806
807 pub
812 fn new_interval_with_init_delay(delay_time: RelativeTime, intev_time: RelativeTime) -> Self
813 {
814 return Self::IntervalDelayed { delay_tm: delay_time, interv_tm: intev_time };
815 }
816}
817
818impl<TIMERTYPE: ModeTimeType> TimerExpMode<TIMERTYPE>
819{
820 #[inline]
822 pub
823 fn reset() -> Self
824 {
825 return Self::None;
826 }
827}
828
829impl<TIMERTYPE: ModeTimeType> fmt::Display for TimerExpMode<TIMERTYPE>
830{
831 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
832 {
833 match self
834 {
835 Self::None =>
836 write!(f, "disarmed"),
837 Self::OneShot{ timeout } =>
838 write!(f, "oneshot {}", timeout),
839 Self::IntervalDelayed
840 { delay_tm, interv_tm } =>
841 write!(f, "interval {} with delay {}", interv_tm, delay_tm),
842 Self::Interval{ interv_tm } =>
843 write!(f, "interval {}", interv_tm),
844 }
845 }
846}
847
848
849
850#[derive(Debug, Clone, PartialEq, Eq)]
869pub enum TimerReadRes<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq>
870{
871 Ok(T),
873
874 Cancelled,
881
882 WouldBlock,
885}
886
887impl TimerReadRes<u64>
888{
889 pub
890 fn ok() -> Self
891 {
892 return Self::Ok(1);
893 }
894}
895
896impl<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq> From<io::Error> for TimerReadRes<T>
897{
898 fn from(value: io::Error) -> Self
899 {
900 if let Some(errn) = value.raw_os_error()
901 {
902 if errn == ECANCELED
903 {
904 return Self::Cancelled;
905 }
906 else if errn == EWOULDBLOCK
907 {
908 return Self::WouldBlock;
909 }
910 }
911
912 return Self::Cancelled;
913 }
914}
915
916impl<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq> fmt::Display for TimerReadRes<T>
917{
918 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
919 {
920 match self
921 {
922 Self::Ok(ovfl) =>
923 write!(f, "OK(overflows:{})", ovfl),
924 Self::Cancelled =>
925 write!(f, "CANCELLED"),
926 Self::WouldBlock =>
927 write!(f, "WOULDBLOCK"),
928 }
929 }
930}
931
932impl<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq> TimerReadRes<T>
933{
934 pub
935 fn unwrap(self) -> T
936 {
937 let Self::Ok(t) = self
938 else { panic!("can not unwrap {:?}", self)};
939
940 return t;
941 }
942}
943
944pub trait FdTimerCom
946{
947 fn new(label: Cow<'static, str>, timer_type: TimerType, timer_flags: TimerFlags) -> TimerPortResult<Self>
961 where Self: Sized;
962
963 fn read(&self) -> TimerPortResult<TimerReadRes<u64>>;
966
967 fn set_time<TIMERTYPE: ModeTimeType>(&self, timer_exp: TimerExpMode<TIMERTYPE>) -> TimerPortResult<()>;
969
970 fn unset_time(&self) -> TimerPortResult<()>;
972}
973
974pub use nix::libc::{itimerspec, timespec};
975
976impl<TIMERTYPE: ModeTimeType> From<itimerspec> for TimerExpMode<TIMERTYPE>
978{
979 fn from(value: itimerspec) -> Self
980 {
981 if value.it_interval.tv_sec == 0 && value.it_interval.tv_nsec == 0 &&
982 value.it_value.tv_sec == 0 && value.it_value.tv_nsec == 0
983 {
984 return Self::None;
986 }
987 else if value.it_interval.tv_sec == 0 && value.it_interval.tv_nsec == 0
988 {
989 return
991 Self::OneShot
992 {
993 timeout: TIMERTYPE::new(value.it_value)
994 };
995 }
996 else if value.it_interval.tv_sec == value.it_value.tv_sec &&
997 value.it_interval.tv_nsec == value.it_value.tv_nsec
998 {
999 return
1001 Self::Interval
1002 {
1003 interv_tm: TIMERTYPE::new(value.it_interval)
1004 };
1005 }
1006 else
1007 {
1008 return
1010 Self::IntervalDelayed
1011 {
1012 delay_tm: TIMERTYPE::new(value.it_value),
1013 interv_tm: TIMERTYPE::new(value.it_interval)
1014 };
1015 }
1016 }
1017}
1018
1019
1020impl<TIMERTYPE: ModeTimeType> From<TimerExpMode<TIMERTYPE>> for itimerspec
1021{
1022 fn from(value: TimerExpMode<TIMERTYPE>) -> Self
1023 {
1024 return (&value).into();
1025 }
1026}
1027
1028impl<TIMERTYPE: ModeTimeType> From<&TimerExpMode<TIMERTYPE>> for itimerspec
1031{
1032 fn from(value: &TimerExpMode<TIMERTYPE>) -> Self
1033 {
1034 match value
1035 {
1036 TimerExpMode::None =>
1037 return
1038 itimerspec
1039 {
1040 it_interval: timespec
1041 {
1042 tv_sec: 0,
1043 tv_nsec: 0,
1044 },
1045 it_value: timespec
1046 {
1047 tv_sec: 0,
1048 tv_nsec: 0,
1049 },
1050 },
1051 TimerExpMode::OneShot{ timeout} =>
1052 return
1053 itimerspec
1054 {
1055 it_interval: timespec
1056 {
1057 tv_sec: 0,
1058 tv_nsec: 0,
1059 },
1060 it_value: timespec
1061 {
1062 tv_sec: timeout.get_sec(),
1063 tv_nsec: timeout.get_nsec(),
1064 },
1065 },
1066 TimerExpMode::IntervalDelayed{ delay_tm, interv_tm } =>
1067 return
1068 itimerspec
1069 {
1070 it_interval: timespec
1071 {
1072 tv_sec: interv_tm.get_sec(),
1073 tv_nsec: interv_tm.get_nsec(),
1074 },
1075 it_value: timespec
1076 {
1077 tv_sec: delay_tm.get_sec(),
1078 tv_nsec: delay_tm.get_nsec(),
1079 },
1080 },
1081 TimerExpMode::Interval{ interv_tm } =>
1082 return
1083 itimerspec
1084 {
1085 it_interval: timespec
1086 {
1087 tv_sec: interv_tm.get_sec(),
1088 tv_nsec: interv_tm.get_nsec(),
1089 },
1090 it_value: timespec
1091 {
1092 tv_sec: interv_tm.get_sec(),
1093 tv_nsec: interv_tm.get_nsec(),
1094 },
1095 }
1096 }
1097 }
1098}
1099
1100
1101#[cfg(test)]
1102mod tests
1103{
1104
1105 use crate::{common, timer_portable::timer::{AbsoluteTime, ModeTimeType, RelativeTime, TimerExpMode}};
1106
1107 #[test]
1108 fn test_0()
1109 {
1110 let ts = common::get_current_timestamp();
1111
1112 let texp1 = TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1113
1114 assert_eq!(
1115 TimerExpMode::OneShot { timeout: AbsoluteTime::from(ts) },
1116 texp1
1117 );
1118
1119 }
1120
1121 #[test]
1122 fn test_1()
1123 {
1124 let ts = common::get_current_timestamp();
1125
1126 let texp1 =
1127 TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1128
1129 let texp2 =
1130 texp1 + RelativeTime::new_time(1, 0);
1131
1132 assert_eq!(texp1 < texp2, true);
1133 assert_eq!(texp2 > texp1, true);
1134 assert_eq!(texp2 != texp1, true);
1135 assert_eq!(texp2 < texp1, false);
1136 }
1137
1138 #[test]
1139 fn test_2()
1140 {
1141
1142 let texp1 =
1143 TimerExpMode::<AbsoluteTime>::new_oneshot(
1144 unsafe {AbsoluteTime::new_time_unchecked(100, AbsoluteTime::MAX_NS)}
1145 );
1146
1147 let texp2 =
1148 texp1 + RelativeTime::new_time(0, 1);
1149
1150
1151 assert_eq!(texp1 < texp2, true);
1152 assert_eq!(texp2 > texp1, true);
1153 assert_eq!(texp2 != texp1, true);
1154 assert_eq!(texp2 < texp1, false);
1155 }
1156
1157 #[should_panic]
1158 #[test]
1159 fn test_2_fail()
1160 {
1161 let ts = common::get_current_timestamp();
1162
1163 let texp1 =
1164 TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1165
1166 let texp2 =
1167 TimerExpMode::<AbsoluteTime>::Interval { interv_tm: AbsoluteTime::from(ts)};
1168
1169 assert_eq!(texp1 == texp2, true);
1170 }
1171
1172 #[test]
1173 fn test_abstime_cmp()
1174 {
1175 let abs_time = AbsoluteTime::now();
1176 let abs_time_future = abs_time + RelativeTime::new_time(10, 1);
1177 let abs_time_past = abs_time - RelativeTime::new_time(10, 1);
1178
1179 assert_eq!(abs_time < abs_time_future, true);
1180 assert_eq!(abs_time_future > abs_time, true);
1181 assert_eq!(abs_time > abs_time_past, true);
1182 assert_eq!(abs_time_past < abs_time, true);
1183 assert_eq!(abs_time_future > abs_time_past, true);
1184 assert_eq!(abs_time_past < abs_time_future, true);
1185 }
1186
1187 #[test]
1188 fn test_abstime_new()
1189 {
1190 let abs = AbsoluteTime::new_time(1, 999_999_999).unwrap();
1191 assert_eq!(abs.time_nsec, 999_999_999);
1192 assert_eq!(abs.time_sec, 1);
1193
1194 let abs = AbsoluteTime::new_time(1, 1_000_000_000).unwrap();
1195 assert_eq!(abs.time_nsec, 0);
1196 assert_eq!(abs.time_sec, 2);
1197
1198 let abs = AbsoluteTime::new_time(1, 1_000_000_001).unwrap();
1199 assert_eq!(abs.time_nsec, 1);
1200 assert_eq!(abs.time_sec, 2);
1201
1202 let abs = AbsoluteTime::new_time(1, 2_000_000_001).unwrap();
1203 assert_eq!(abs.time_nsec, 1);
1204 assert_eq!(abs.time_sec, 3);
1205 }
1206
1207 #[test]
1208 fn test_abstime_add()
1209 {
1210 let mut abs = AbsoluteTime::new_time(1, 999_999_999).unwrap();
1211
1212 abs += RelativeTime::new_time(0, 1);
1213
1214 assert_eq!(abs.time_nsec, 0);
1215 assert_eq!(abs.time_sec, 2);
1216
1217 abs += RelativeTime::new_time(1, 1);
1218
1219 assert_eq!(abs.time_nsec, 1);
1220 assert_eq!(abs.time_sec, 3);
1221
1222 abs += RelativeTime::new_time(0, 999_999_999);
1223
1224 assert_eq!(abs.time_nsec, 0);
1225 assert_eq!(abs.time_sec, 4);
1226
1227 abs -= RelativeTime::new_time(0, 999_999_999);
1228
1229 assert_eq!(abs.time_nsec, 1);
1230 assert_eq!(abs.time_sec, 3);
1231
1232 abs -= RelativeTime::new_time(0, 1);
1233
1234 assert_eq!(abs.time_nsec, 0);
1235 assert_eq!(abs.time_sec, 3);
1236
1237 abs -= RelativeTime::new_time(0, 500_000_000);
1238
1239 assert_eq!(abs.time_nsec, 500_000_000);
1240 assert_eq!(abs.time_sec, 2);
1241
1242 abs -= RelativeTime::new_time(0, 400_000_000);
1243
1244 assert_eq!(abs.time_nsec, 100_000_000);
1245 assert_eq!(abs.time_sec, 2);
1246
1247 abs -= RelativeTime::new_time(1, 200_000_000);
1248
1249 assert_eq!(abs.time_nsec, 900_000_000);
1250 assert_eq!(abs.time_sec, 0);
1251 }
1252}