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, PartialEq, Eq)]
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<()>;
973
974 fn unset_time(&self) -> TimerPortResult<()>;
976}
977
978pub use nix::libc::{itimerspec, timespec};
979
980impl<TIMERTYPE: ModeTimeType> From<itimerspec> for TimerExpMode<TIMERTYPE>
982{
983 fn from(value: itimerspec) -> Self
984 {
985 if value.it_interval.tv_sec == 0 && value.it_interval.tv_nsec == 0 &&
986 value.it_value.tv_sec == 0 && value.it_value.tv_nsec == 0
987 {
988 return Self::None;
990 }
991 else if value.it_interval.tv_sec == 0 && value.it_interval.tv_nsec == 0
992 {
993 return
995 Self::OneShot
996 {
997 timeout: TIMERTYPE::new(value.it_value)
998 };
999 }
1000 else if value.it_interval.tv_sec == value.it_value.tv_sec &&
1001 value.it_interval.tv_nsec == value.it_value.tv_nsec
1002 {
1003 return
1005 Self::Interval
1006 {
1007 interv_tm: TIMERTYPE::new(value.it_interval)
1008 };
1009 }
1010 else
1011 {
1012 return
1014 Self::IntervalDelayed
1015 {
1016 delay_tm: TIMERTYPE::new(value.it_value),
1017 interv_tm: TIMERTYPE::new(value.it_interval)
1018 };
1019 }
1020 }
1021}
1022
1023
1024impl<TIMERTYPE: ModeTimeType> From<TimerExpMode<TIMERTYPE>> for itimerspec
1025{
1026 fn from(value: TimerExpMode<TIMERTYPE>) -> Self
1027 {
1028 return (&value).into();
1029 }
1030}
1031
1032impl<TIMERTYPE: ModeTimeType> From<&TimerExpMode<TIMERTYPE>> for itimerspec
1035{
1036 fn from(value: &TimerExpMode<TIMERTYPE>) -> Self
1037 {
1038 match value
1039 {
1040 TimerExpMode::None =>
1041 return
1042 itimerspec
1043 {
1044 it_interval: timespec
1045 {
1046 tv_sec: 0,
1047 tv_nsec: 0,
1048 },
1049 it_value: timespec
1050 {
1051 tv_sec: 0,
1052 tv_nsec: 0,
1053 },
1054 },
1055 TimerExpMode::OneShot{ timeout} =>
1056 return
1057 itimerspec
1058 {
1059 it_interval: timespec
1060 {
1061 tv_sec: 0,
1062 tv_nsec: 0,
1063 },
1064 it_value: timespec
1065 {
1066 tv_sec: timeout.get_sec(),
1067 tv_nsec: timeout.get_nsec(),
1068 },
1069 },
1070 TimerExpMode::IntervalDelayed{ delay_tm, interv_tm } =>
1071 return
1072 itimerspec
1073 {
1074 it_interval: timespec
1075 {
1076 tv_sec: interv_tm.get_sec(),
1077 tv_nsec: interv_tm.get_nsec(),
1078 },
1079 it_value: timespec
1080 {
1081 tv_sec: delay_tm.get_sec(),
1082 tv_nsec: delay_tm.get_nsec(),
1083 },
1084 },
1085 TimerExpMode::Interval{ interv_tm } =>
1086 return
1087 itimerspec
1088 {
1089 it_interval: timespec
1090 {
1091 tv_sec: interv_tm.get_sec(),
1092 tv_nsec: interv_tm.get_nsec(),
1093 },
1094 it_value: timespec
1095 {
1096 tv_sec: interv_tm.get_sec(),
1097 tv_nsec: interv_tm.get_nsec(),
1098 },
1099 }
1100 }
1101 }
1102}
1103
1104
1105#[cfg(test)]
1106mod tests
1107{
1108
1109 use crate::{common, timer_portable::timer::{AbsoluteTime, ModeTimeType, RelativeTime, TimerExpMode}};
1110
1111 #[test]
1112 fn test_0()
1113 {
1114 let ts = common::get_current_timestamp();
1115
1116 let texp1 = TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1117
1118 assert_eq!(
1119 TimerExpMode::OneShot { timeout: AbsoluteTime::from(ts) },
1120 texp1
1121 );
1122
1123 }
1124
1125 #[test]
1126 fn test_1()
1127 {
1128 let ts = common::get_current_timestamp();
1129
1130 let texp1 =
1131 TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1132
1133 let texp2 =
1134 texp1 + RelativeTime::new_time(1, 0);
1135
1136 assert_eq!(texp1 < texp2, true);
1137 assert_eq!(texp2 > texp1, true);
1138 assert_eq!(texp2 != texp1, true);
1139 assert_eq!(texp2 < texp1, false);
1140 }
1141
1142 #[test]
1143 fn test_2()
1144 {
1145
1146 let texp1 =
1147 TimerExpMode::<AbsoluteTime>::new_oneshot(
1148 unsafe {AbsoluteTime::new_time_unchecked(100, AbsoluteTime::MAX_NS)}
1149 );
1150
1151 let texp2 =
1152 texp1 + RelativeTime::new_time(0, 1);
1153
1154
1155 assert_eq!(texp1 < texp2, true);
1156 assert_eq!(texp2 > texp1, true);
1157 assert_eq!(texp2 != texp1, true);
1158 assert_eq!(texp2 < texp1, false);
1159 }
1160
1161 #[should_panic]
1162 #[test]
1163 fn test_2_fail()
1164 {
1165 let ts = common::get_current_timestamp();
1166
1167 let texp1 =
1168 TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1169
1170 let texp2 =
1171 TimerExpMode::<AbsoluteTime>::Interval { interv_tm: AbsoluteTime::from(ts)};
1172
1173 assert_eq!(texp1 == texp2, true);
1174 }
1175
1176 #[test]
1177 fn test_abstime_cmp()
1178 {
1179 let abs_time = AbsoluteTime::now();
1180 let abs_time_future = abs_time + RelativeTime::new_time(10, 1);
1181 let abs_time_past = abs_time - RelativeTime::new_time(10, 1);
1182
1183 assert_eq!(abs_time < abs_time_future, true);
1184 assert_eq!(abs_time_future > abs_time, true);
1185 assert_eq!(abs_time > abs_time_past, true);
1186 assert_eq!(abs_time_past < abs_time, true);
1187 assert_eq!(abs_time_future > abs_time_past, true);
1188 assert_eq!(abs_time_past < abs_time_future, true);
1189 }
1190
1191 #[test]
1192 fn test_abstime_new()
1193 {
1194 let abs = AbsoluteTime::new_time(1, 999_999_999).unwrap();
1195 assert_eq!(abs.time_nsec, 999_999_999);
1196 assert_eq!(abs.time_sec, 1);
1197
1198 let abs = AbsoluteTime::new_time(1, 1_000_000_000).unwrap();
1199 assert_eq!(abs.time_nsec, 0);
1200 assert_eq!(abs.time_sec, 2);
1201
1202 let abs = AbsoluteTime::new_time(1, 1_000_000_001).unwrap();
1203 assert_eq!(abs.time_nsec, 1);
1204 assert_eq!(abs.time_sec, 2);
1205
1206 let abs = AbsoluteTime::new_time(1, 2_000_000_001).unwrap();
1207 assert_eq!(abs.time_nsec, 1);
1208 assert_eq!(abs.time_sec, 3);
1209 }
1210
1211 #[test]
1212 fn test_abstime_add()
1213 {
1214 let mut abs = AbsoluteTime::new_time(1, 999_999_999).unwrap();
1215
1216 abs += RelativeTime::new_time(0, 1);
1217
1218 assert_eq!(abs.time_nsec, 0);
1219 assert_eq!(abs.time_sec, 2);
1220
1221 abs += RelativeTime::new_time(1, 1);
1222
1223 assert_eq!(abs.time_nsec, 1);
1224 assert_eq!(abs.time_sec, 3);
1225
1226 abs += RelativeTime::new_time(0, 999_999_999);
1227
1228 assert_eq!(abs.time_nsec, 0);
1229 assert_eq!(abs.time_sec, 4);
1230
1231 abs -= RelativeTime::new_time(0, 999_999_999);
1232
1233 assert_eq!(abs.time_nsec, 1);
1234 assert_eq!(abs.time_sec, 3);
1235
1236 abs -= RelativeTime::new_time(0, 1);
1237
1238 assert_eq!(abs.time_nsec, 0);
1239 assert_eq!(abs.time_sec, 3);
1240
1241 abs -= RelativeTime::new_time(0, 500_000_000);
1242
1243 assert_eq!(abs.time_nsec, 500_000_000);
1244 assert_eq!(abs.time_sec, 2);
1245
1246 abs -= RelativeTime::new_time(0, 400_000_000);
1247
1248 assert_eq!(abs.time_nsec, 100_000_000);
1249 assert_eq!(abs.time_sec, 2);
1250
1251 abs -= RelativeTime::new_time(1, 200_000_000);
1252
1253 assert_eq!(abs.time_nsec, 900_000_000);
1254 assert_eq!(abs.time_sec, 0);
1255 }
1256}