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
22use crate::{common, timer_portable::portable_error::TimerPortResult};
23
24#[cfg(target_os = "linux")]
25pub use super::linux::timer_fd_linux::*;
26
27#[cfg(any(
28 target_os = "freebsd",
29 target_os = "dragonfly",
30 target_os = "netbsd",
31 target_os = "openbsd",
32 target_os = "macos",
33))]
34pub use super::bsd::timer_kqueue_bsd::*;
35
36
37#[allow(non_camel_case_types)]
39#[derive(Debug)]
40pub enum TimerType
41{
42 CLOCK_REALTIME,
44
45 CLOCK_MONOTONIC,
50
51 CLOCK_BOOTTIME,
59
60 CLOCK_REALTIME_ALARM,
64
65 CLOCK_BOOTTIME_ALARM,
69}
70
71impl Into<libc::clockid_t> for TimerType
72{
73 fn into(self) -> libc::clockid_t
74 {
75 match self
76 {
77 Self::CLOCK_REALTIME => return libc::CLOCK_REALTIME,
78 Self::CLOCK_MONOTONIC => return libc::CLOCK_MONOTONIC,
79 #[cfg(target_os = "linux")]
80 Self::CLOCK_BOOTTIME => return libc::CLOCK_BOOTTIME,
81 #[cfg(target_os = "linux")]
82 Self::CLOCK_REALTIME_ALARM => return libc::CLOCK_REALTIME_ALARM,
83 #[cfg(target_os = "linux")]
84 Self::CLOCK_BOOTTIME_ALARM => return libc::CLOCK_BOOTTIME_ALARM,
85 #[cfg(any(
86 target_os = "freebsd",
87 target_os = "dragonfly",
88 target_os = "netbsd",
89 target_os = "openbsd",
90 target_os = "macos",
91 ))]
92 _ => return libc::CLOCK_REALTIME,
93 }
94 }
95}
96
97#[cfg(target_os = "linux")]
98bitflags! {
99 #[derive(Default)]
101 pub struct TimerFlags: i32
102 {
103 const TFD_NONBLOCK = libc::TFD_NONBLOCK;
108
109 const TFD_CLOEXEC = libc::TFD_CLOEXEC;
113 }
114}
115
116#[cfg(any(
117 target_os = "freebsd",
118 target_os = "dragonfly",
119 target_os = "netbsd",
120 target_os = "openbsd",
121 target_os = "macos",
122))]
123bitflags! {
124 #[derive(Default)]
126 pub struct TimerFlags: i32
127 {
128 const TFD_NONBLOCK = 0;
130
131 const TFD_CLOEXEC = 0;
133 }
134}
135
136#[cfg(target_os = "linux")]
137bitflags! {
138 #[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
140 pub struct TimerSetTimeFlags: i32
141 {
142 const TFD_TIMER_ABSTIME = libc::TFD_TIMER_ABSTIME;
146
147 const TFD_TIMER_CANCEL_ON_SET = (1 << 1);
155 }
156}
157
158#[cfg(any(
159 target_os = "freebsd",
160 target_os = "dragonfly",
161 target_os = "netbsd",
162 target_os = "openbsd",
163 target_os = "macos",
164))]
165
166bitflags! {
167 #[derive(Default)]
169 pub struct TimerSetTimeFlags: i32
170 {
171 const TFD_TIMER_ABSTIME = 0;
173
174 const TFD_TIMER_CANCEL_ON_SET = 0;
176 }
177}
178
179pub trait ModeTimeType: Eq + PartialEq + Ord + PartialOrd + fmt::Display + fmt::Debug + Clone + Copy
187{
188 fn new(tv_sec: i64, tv_nsec: i64) -> Self where Self: Sized;
201
202 fn get_sec(&self) -> i64;
204
205 fn get_nsec(&self) -> i64;
207
208 fn is_value_valid(&self) -> bool;
210
211 fn get_flags() -> TimerSetTimeFlags;
214}
215
216#[derive(Debug, PartialEq, Eq, Clone, Copy)]
218pub struct RelativeTime
219{
220 time_sec: i64,
222
223 time_nsec: i64,
225}
226
227impl From<Duration> for RelativeTime
230{
231 fn from(value: Duration) -> Self
232 {
233 return Self
234 {
235 time_sec:
236 value.as_secs() as i64,
237 time_nsec:
238 value.subsec_nanos() as i64,
239 };
240 }
241}
242
243impl Ord for RelativeTime
244{
245 fn cmp(&self, other: &Self) -> Ordering
246 {
247 return
248 self
249 .time_sec
250 .cmp(&other.time_sec)
251 .then(
252 self
253 .time_nsec
254 .cmp(&other.time_nsec)
255 );
256 }
257}
258
259impl PartialOrd for RelativeTime
260{
261 fn partial_cmp(&self, other: &Self) -> Option<Ordering>
262 {
263 return Some(self.cmp(other));
264 }
265}
266
267impl fmt::Display for RelativeTime
268{
269 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
270 {
271 write!(f, "[relative] sec: {}, nsec: {}", self.time_sec, self.time_nsec)
272 }
273}
274
275impl ModeTimeType for RelativeTime
276{
277 fn new(tv_sec: i64, tv_nsec: i64) -> RelativeTime
278 {
279 return
280 Self::new_time(tv_sec, tv_nsec);
281 }
282
283 fn get_sec(&self) -> i64
284 {
285 return self.time_sec;
286 }
287
288 fn get_nsec(&self) -> i64 {
289
290 return self.time_nsec;
291 }
292
293 fn is_value_valid(&self) -> bool
294 {
295 return true;
296 }
297
298 fn get_flags() -> TimerSetTimeFlags
299 {
300 return TimerSetTimeFlags::empty();
301 }
302}
303
304impl RelativeTime
305{
306 pub const MAX_NS: i64 = 1_000_000_000;
308
309 pub
323 fn new_time(time_sec: i64, time_nsec: i64) -> Self
324 {
325 let extra_sec = time_nsec / Self::MAX_NS;
326 let nsec_new = time_nsec % Self::MAX_NS;
327
328 return
329 Self
330 {
331 time_nsec: nsec_new,
332 time_sec: time_sec + extra_sec,
333 };
334 }
335}
336
337#[derive(Debug, PartialEq, Eq, Clone, Copy)]
340pub struct AbsoluteTime
341{
342 time_sec: i64,
344
345 time_nsec: i64,
347}
348
349impl<TZ: TimeZone> From<DateTime<TZ>> for AbsoluteTime
353{
354 fn from(value: DateTime<TZ>) -> Self
355 {
356 return Self
357 {
358 time_sec:
359 value.timestamp(),
360 time_nsec:
361 value.timestamp_subsec_nanos() as i64,
362 };
363 }
364}
365
366impl From<Duration> for AbsoluteTime
369{
370 fn from(value: Duration) -> Self
371 {
372 return Self
373 {
374 time_sec:
375 value.as_secs() as i64,
376 time_nsec:
377 value.subsec_nanos() as i64,
378 };
379 }
380}
381
382impl Ord for AbsoluteTime
383{
384 fn cmp(&self, other: &Self) -> Ordering
385 {
386 return
387 self
388 .time_sec
389 .cmp(&other.time_sec)
390 .then(
391 self
392 .time_nsec
393 .cmp(&other.time_nsec)
394 );
395 }
396}
397
398impl PartialOrd for AbsoluteTime
399{
400 fn partial_cmp(&self, other: &Self) -> Option<Ordering>
401 {
402 return Some(self.cmp(other));
403 }
404}
405
406impl ops::AddAssign<RelativeTime> for AbsoluteTime
407{
408 fn add_assign(&mut self, rhs: RelativeTime)
409 {
410 self.time_nsec += rhs.time_nsec;
411 let add_sec = self.time_nsec / Self::MAX_NS;
412
413 if add_sec > 0
414 {
415 self.time_nsec %= Self::MAX_NS;
416 }
417
418 self.time_sec += rhs.time_sec + add_sec;
419 }
420}
421
422impl ops::Add<RelativeTime> for AbsoluteTime
423{
424 type Output = AbsoluteTime;
425
426 fn add(mut self, rhs: RelativeTime) -> Self::Output
427 {
428 self += rhs;
429
430 return self;
431 }
432}
433
434impl ops::SubAssign<RelativeTime> for AbsoluteTime
435{
436 fn sub_assign(&mut self, mut rhs: RelativeTime)
437 {
438
439 let mut nsec = self.time_nsec - rhs.time_nsec;
440
441 if nsec < 0
442 {
443 rhs.time_sec += 1;
444
445 nsec = Self::MAX_NS + nsec;
446 }
447
448 self.time_nsec = nsec;
449 self.time_sec -= rhs.time_sec;
450
451 return;
452 }
453}
454
455impl ops::Sub<RelativeTime> for AbsoluteTime
456{
457 type Output = AbsoluteTime;
458
459 fn sub(mut self, rhs: RelativeTime) -> Self::Output
460 {
461 self -= rhs;
462
463 return self;
464 }
465}
466
467impl ops::SubAssign for AbsoluteTime
468{
469 fn sub_assign(&mut self, mut rhs: Self)
470 {
471
472 let mut nsec = self.time_nsec - rhs.time_nsec;
473
474 if nsec < 0
475 {
476 rhs.time_sec += 1;
477
478 nsec = Self::MAX_NS + nsec;
479 }
480
481 self.time_nsec = nsec;
482 self.time_sec -= rhs.time_sec;
483
484 return;
485 }
486}
487
488impl ops::Sub for AbsoluteTime
489{
490 type Output = AbsoluteTime;
491
492 fn sub(mut self, rhs: Self) -> Self::Output
493 {
494 self -= rhs;
495
496 return self;
497 }
498}
499
500
501impl fmt::Display for AbsoluteTime
502{
503 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
504 {
505 write!(f, "[absolute] {}.{}sec", self.time_sec, self.time_nsec)
506 }
507}
508
509
510impl ModeTimeType for AbsoluteTime
511{
512 fn new(tv_sec: i64, tv_nsec: i64) -> Self where Self: Sized
513 {
514 return
515 Self::new_time(tv_sec, tv_nsec);
516 }
517
518 fn get_sec(&self) -> i64
519 {
520 return self.time_sec;
521 }
522
523 fn get_nsec(&self) -> i64
524 {
525
526 return self.time_nsec;
527 }
528
529 fn is_value_valid(&self) -> bool
530 {
531 return self.time_nsec != 0 || self.time_sec != 0;
532 }
533
534 fn get_flags() -> TimerSetTimeFlags
535 {
536 return TimerSetTimeFlags::TFD_TIMER_ABSTIME | TimerSetTimeFlags::TFD_TIMER_CANCEL_ON_SET;
537 }
538}
539
540impl AbsoluteTime
541{
542 pub const MAX_NS: i64 = 1_000_000_000;}
545
546impl AbsoluteTime
547{
548 pub
550 fn now() -> Self
551 {
552 let value = common::get_current_timestamp();
553
554 return Self
555 {
556 time_sec: value.timestamp(),
557 time_nsec: value.timestamp_subsec_nanos() as i64,
558 }
559 }
560
561 pub
579 fn new_time(time_sec: i64, time_nsec: i64) -> Self
580 {
581 let extra_sec = time_nsec / Self::MAX_NS;
582 let nsec_new = time_nsec % Self::MAX_NS;
583
584 return
585 Self
586 {
587 time_nsec: nsec_new,
588 time_sec: time_sec + extra_sec,
589 };
590 }
591
592 pub
594 fn seconds_cmp(&self, other: &Self) -> Ordering
595 {
596 return self.time_sec.cmp(&other.time_sec);
597 }
598
599 pub
600 fn add_sec(mut self, seconds: i64) -> Self
601 {
602 self.time_sec += seconds;
603
604 return self;
605 }
606
607 pub
608 fn reset_nsec(mut self) -> Self
609 {
610 self.time_nsec = 0;
611
612 return self;
613 }
614}
615
616pub trait TimerExpModeInto: Into<itimerspec>
622{
623 fn is_valid(&self) -> bool;
627
628 fn get_flags(&self) -> TimerSetTimeFlags;
630}
631
632
633
634#[derive(Clone, Copy, Debug, PartialEq, Eq)]
639pub enum TimerExpMode<TIMERTYPE: ModeTimeType>
640{
641 None,
643
644 OneShot
646 {
647 timeout: TIMERTYPE
648 },
649
650 IntervalDelayed
652 {
653 delay_tm: TIMERTYPE,
655
656 interv_tm: TIMERTYPE
658 },
659
660 Interval
663 {
664 interv_tm: TIMERTYPE
666 },
667}
668
669
670impl ops::AddAssign<RelativeTime> for TimerExpMode<AbsoluteTime>
671{
672 fn add_assign(&mut self, rhs: RelativeTime)
673 {
674 match self
675 {
676 TimerExpMode::None =>
677 return,
678 TimerExpMode::OneShot { timeout } =>
679 {
680 *timeout += rhs;
681
682 },
683 TimerExpMode::IntervalDelayed { interv_tm, .. } =>
684 {
685 *interv_tm += rhs;
686 },
687 TimerExpMode::Interval { interv_tm } =>
688 {
689 *interv_tm += rhs;
690 },
691 }
692 }
693}
694
695
696impl ops::Add<RelativeTime> for TimerExpMode<AbsoluteTime>
697{
698 type Output = TimerExpMode<AbsoluteTime>;
699
700 fn add(mut self, rhs: RelativeTime) -> Self::Output
701 {
702 self += rhs;
703
704 return self;
705 }
706}
707
708
709impl<TIMERTYPE: ModeTimeType> Ord for TimerExpMode<TIMERTYPE>
710{
711 fn cmp(&self, other: &Self) -> Ordering
712 {
713 match (self, other)
714 {
715 (TimerExpMode::None, TimerExpMode::None) =>
716 return Ordering::Equal,
717 (TimerExpMode::OneShot{ timeout }, TimerExpMode::OneShot { timeout: timeout2 }) =>
718 {
719 return timeout.cmp(timeout2);
720 },
721 (
722 TimerExpMode::IntervalDelayed{ delay_tm, interv_tm },
723 TimerExpMode::IntervalDelayed{ delay_tm: delay_tm2, interv_tm: interv_tm2 }
724 ) =>
725 {
726 return
727 delay_tm.cmp(delay_tm2)
728 .then(interv_tm.cmp(interv_tm2));
729 },
730 (TimerExpMode::Interval { interv_tm }, TimerExpMode::Interval { interv_tm: interv_tm2 }) =>
731 {
732 return interv_tm.cmp(interv_tm2);
733 },
734 _ =>
735 panic!("cannot compare different types {} and {}", self, other)
736 }
737 }
738}
739
740impl<TIMERTYPE: ModeTimeType> PartialOrd for TimerExpMode<TIMERTYPE>
741{
742 fn partial_cmp(&self, other: &Self) -> Option<Ordering>
743 {
744 return Some(self.cmp(other));
745 }
746}
747
748impl TimerExpModeInto for TimerExpMode<AbsoluteTime>
749{
750 #[inline]
751 fn is_valid(&self) -> bool
752 {
753 return self.is_valid_inner();
754 }
755
756 #[inline]
757 fn get_flags(&self) -> TimerSetTimeFlags
758 {
759 return AbsoluteTime::get_flags();
760 }
761}
762
763impl TimerExpMode<AbsoluteTime>
765{
766 #[inline]
769 fn is_valid_inner(&self) -> bool
770 {
771 match self
772 {
773 Self::None =>
774 return false,
775 Self::OneShot{ timeout} =>
776 return timeout.is_value_valid(),
777 Self::IntervalDelayed{ delay_tm, interv_tm } =>
778 return delay_tm.is_value_valid() && interv_tm.is_value_valid(),
779 Self::Interval{ interv_tm } =>
780 return interv_tm.is_value_valid()
781 }
782 }
783
784 pub
788 fn new_oneshot(abs_time: AbsoluteTime) -> Self
789 {
790 return Self::OneShot { timeout: abs_time };
791 }
792}
793
794impl TimerExpModeInto for TimerExpMode<RelativeTime>
795{
796 #[inline]
797 fn is_valid(&self) -> bool
798 {
799 return true;
800 }
801
802 #[inline]
803 fn get_flags(&self) -> TimerSetTimeFlags
804 {
805 return RelativeTime::get_flags();
806 }
807}
808
809impl TimerExpMode<RelativeTime>
811{
812 pub
815 fn new_oneshot(rel_time: RelativeTime) -> Self
816 {
817 return Self::OneShot { timeout: rel_time };
818 }
819
820 pub
823 fn new_interval(rel_time: RelativeTime) -> Self
824 {
825 return Self::Interval { interv_tm: rel_time };
826 }
827
828 pub
833 fn new_interval_with_init_delay(delay_time: RelativeTime, intev_time: RelativeTime) -> Self
834 {
835 return Self::IntervalDelayed { delay_tm: delay_time, interv_tm: intev_time };
836 }
837}
838
839impl<TIMERTYPE: ModeTimeType> TimerExpMode<TIMERTYPE>
840{
841 #[inline]
843 pub
844 fn reset() -> Self
845 {
846 return Self::None;
847 }
848}
849
850impl<TIMERTYPE: ModeTimeType> fmt::Display for TimerExpMode<TIMERTYPE>
851{
852 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
853 {
854 match self
855 {
856 Self::None =>
857 write!(f, "disarmed"),
858 Self::OneShot{ timeout } =>
859 write!(f, "oneshot {}", timeout),
860 Self::IntervalDelayed
861 { delay_tm, interv_tm } =>
862 write!(f, "interval {} with delay {}", interv_tm, delay_tm),
863 Self::Interval{ interv_tm } =>
864 write!(f, "interval {}", interv_tm),
865 }
866 }
867}
868
869#[cfg(any(
870 target_os = "freebsd",
871 target_os = "dragonfly",
872 target_os = "netbsd",
873 target_os = "openbsd",
874 target_os = "macos",
875 target_os = "linux",
876))]
877use nix::libc::{itimerspec, timespec};
878
879#[cfg(target_os = "macos")]
880#[repr(C)]
881pub struct timespec
882{
883 pub tv_sec: libc::time_t,
884 pub tv_nsec: libc::c_long,
885}
886#[cfg(target_os = "macos")]
887#[repr(C)]
888pub struct itimerspec
889{
890 pub it_interval: timespec,
891 pub it_value: timespec,
892}
893
894
895impl<TIMERTYPE: ModeTimeType> From<itimerspec> for TimerExpMode<TIMERTYPE>
897{
898 fn from(value: itimerspec) -> Self
899 {
900 if value.it_interval.tv_sec == 0 && value.it_interval.tv_nsec == 0 &&
901 value.it_value.tv_sec == 0 && value.it_value.tv_nsec == 0
902 {
903 return Self::None;
905 }
906 else if value.it_interval.tv_sec == 0 && value.it_interval.tv_nsec == 0
907 {
908 return
910 Self::OneShot
911 {
912 timeout: TIMERTYPE::new(value.it_value.tv_sec, value.it_value.tv_nsec)
913 };
914 }
915 else if value.it_interval.tv_sec == value.it_value.tv_sec &&
916 value.it_interval.tv_nsec == value.it_value.tv_nsec
917 {
918 return
920 Self::Interval
921 {
922 interv_tm: TIMERTYPE::new(value.it_interval.tv_sec, value.it_interval.tv_nsec)
923 };
924 }
925 else
926 {
927 return
929 Self::IntervalDelayed
930 {
931 delay_tm: TIMERTYPE::new(value.it_value.tv_sec, value.it_value.tv_nsec) ,
932 interv_tm: TIMERTYPE::new(value.it_interval.tv_sec, value.it_interval.tv_nsec)
933 };
934 }
935 }
936}
937
938impl<TIMERTYPE: ModeTimeType> From<TimerExpMode<TIMERTYPE>> for itimerspec
939{
940 fn from(value: TimerExpMode<TIMERTYPE>) -> Self
941 {
942 return (&value).into();
943 }
944}
945
946impl<TIMERTYPE: ModeTimeType> From<&TimerExpMode<TIMERTYPE>> for itimerspec
949{
950 fn from(value: &TimerExpMode<TIMERTYPE>) -> Self
951 {
952 match value
953 {
954 TimerExpMode::None =>
955 return
956 itimerspec
957 {
958 it_interval: timespec
959 {
960 tv_sec: 0,
961 tv_nsec: 0,
962 },
963 it_value: timespec
964 {
965 tv_sec: 0,
966 tv_nsec: 0,
967 },
968 },
969 TimerExpMode::OneShot{ timeout} =>
970 return
971 itimerspec
972 {
973 it_interval: timespec
974 {
975 tv_sec: 0,
976 tv_nsec: 0,
977 },
978 it_value: timespec
979 {
980 tv_sec: timeout.get_sec(),
981 tv_nsec: timeout.get_nsec(),
982 },
983 },
984 TimerExpMode::IntervalDelayed{ delay_tm, interv_tm } =>
985 return
986 itimerspec
987 {
988 it_interval: timespec
989 {
990 tv_sec: interv_tm.get_sec(),
991 tv_nsec: interv_tm.get_nsec(),
992 },
993 it_value: timespec
994 {
995 tv_sec: delay_tm.get_sec(),
996 tv_nsec: delay_tm.get_nsec(),
997 },
998 },
999 TimerExpMode::Interval{ interv_tm } =>
1000 return
1001 itimerspec
1002 {
1003 it_interval: timespec
1004 {
1005 tv_sec: interv_tm.get_sec(),
1006 tv_nsec: interv_tm.get_nsec(),
1007 },
1008 it_value: timespec
1009 {
1010 tv_sec: interv_tm.get_sec(),
1011 tv_nsec: interv_tm.get_nsec(),
1012 },
1013 }
1014 }
1015 }
1016}
1017
1018#[derive(Debug, Clone, PartialEq, Eq)]
1020pub enum TimerReadRes<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq>
1021{
1022 Ok(T),
1024
1025 Cancelled,
1032
1033 WouldBlock,
1036}
1037
1038impl TimerReadRes<u64>
1039{
1040 pub
1041 fn ok() -> Self
1042 {
1043 return Self::Ok(1);
1044 }
1045}
1046
1047impl<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq> From<io::Error> for TimerReadRes<T>
1048{
1049 fn from(value: io::Error) -> Self
1050 {
1051 if let Some(errn) = value.raw_os_error()
1052 {
1053 if errn == ECANCELED
1054 {
1055 return Self::Cancelled;
1056 }
1057 else if errn == EWOULDBLOCK
1058 {
1059 return Self::WouldBlock;
1060 }
1061 }
1062
1063 return Self::Cancelled;
1064 }
1065}
1066
1067impl<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq> fmt::Display for TimerReadRes<T>
1068{
1069 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
1070 {
1071 match self
1072 {
1073 Self::Ok(ovfl) =>
1074 write!(f, "OK(overflows:{})", ovfl),
1075 Self::Cancelled =>
1076 write!(f, "CANCELLED"),
1077 Self::WouldBlock =>
1078 write!(f, "WOULDBLOCK"),
1079 }
1080 }
1081}
1082
1083impl<T: Sized + fmt::Debug + fmt::Display + Clone + Eq + PartialEq> TimerReadRes<T>
1084{
1085 pub
1086 fn unwrap(self) -> T
1087 {
1088 let Self::Ok(t) = self
1089 else { panic!("can not unwrap {:?}", self)};
1090
1091 return t;
1092 }
1093}
1094
1095pub trait FdTimerCom
1097{
1098 fn new(label: Cow<'static, str>, timer_type: TimerType, timer_flags: TimerFlags) -> TimerPortResult<Self>
1112 where Self: Sized;
1113
1114 fn read(&self) -> TimerPortResult<TimerReadRes<u64>>;
1117
1118 fn read_buf(&self, unfilled: &mut [u8]) -> std::io::Result<usize>;
1121
1122 fn set_time<TIMERTYPE: TimerExpModeInto>(&self, timer_exp: TIMERTYPE) -> TimerPortResult<()>;
1124
1125 fn unset_time(&self) -> TimerPortResult<()>;
1127}
1128
1129
1130#[cfg(test)]
1131mod tests
1132{
1133
1134 use crate::{common, timer_portable::timer::{AbsoluteTime, ModeTimeType, RelativeTime, TimerExpMode}};
1135
1136 #[test]
1137 fn test_0()
1138 {
1139 let ts = common::get_current_timestamp();
1140
1141 let texp1 = TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1142
1143 assert_eq!(
1144 TimerExpMode::OneShot { timeout: AbsoluteTime::from(ts) },
1145 texp1
1146 );
1147
1148 }
1149
1150 #[test]
1151 fn test_1()
1152 {
1153 let ts = common::get_current_timestamp();
1154
1155 let texp1 =
1156 TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1157
1158 let texp2 =
1159 texp1 + RelativeTime::new_time(1, 0);
1160
1161 assert_eq!(texp1 < texp2, true);
1162 assert_eq!(texp2 > texp1, true);
1163 assert_eq!(texp2 != texp1, true);
1164 assert_eq!(texp2 < texp1, false);
1165 }
1166
1167 #[test]
1168 fn test_2()
1169 {
1170
1171 let texp1 =
1172 TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::new(100, AbsoluteTime::MAX_NS));
1173
1174 let texp2 =
1175 texp1 + RelativeTime::new_time(0, 1);
1176
1177
1178 assert_eq!(texp1 < texp2, true);
1179 assert_eq!(texp2 > texp1, true);
1180 assert_eq!(texp2 != texp1, true);
1181 assert_eq!(texp2 < texp1, false);
1182 }
1183
1184 #[should_panic]
1185 #[test]
1186 fn test_2_fail()
1187 {
1188 let ts = common::get_current_timestamp();
1189
1190 let texp1 =
1191 TimerExpMode::<AbsoluteTime>::new_oneshot(AbsoluteTime::from(ts));
1192
1193 let texp2 =
1194 TimerExpMode::<AbsoluteTime>::Interval { interv_tm: AbsoluteTime::from(ts)};
1195
1196 assert_eq!(texp1 == texp2, true);
1197 }
1198
1199 #[test]
1200 fn test_abstime_cmp()
1201 {
1202 let abs_time = AbsoluteTime::now();
1203 let abs_time_future = abs_time + RelativeTime::new_time(10, 1);
1204 let abs_time_past = abs_time - RelativeTime::new_time(10, 1);
1205
1206 assert_eq!(abs_time < abs_time_future, true);
1207 assert_eq!(abs_time_future > abs_time, true);
1208 assert_eq!(abs_time > abs_time_past, true);
1209 assert_eq!(abs_time_past < abs_time, true);
1210 assert_eq!(abs_time_future > abs_time_past, true);
1211 assert_eq!(abs_time_past < abs_time_future, true);
1212 }
1213
1214 #[test]
1215 fn test_abstime_new()
1216 {
1217 let abs = AbsoluteTime::new_time(1, 999_999_999);
1218 assert_eq!(abs.time_nsec, 999_999_999);
1219 assert_eq!(abs.time_sec, 1);
1220
1221 let abs = AbsoluteTime::new_time(1, 1_000_000_000);
1222 assert_eq!(abs.time_nsec, 0);
1223 assert_eq!(abs.time_sec, 2);
1224
1225 let abs = AbsoluteTime::new_time(1, 1_000_000_001);
1226 assert_eq!(abs.time_nsec, 1);
1227 assert_eq!(abs.time_sec, 2);
1228
1229 let abs = AbsoluteTime::new_time(1, 2_000_000_001);
1230 assert_eq!(abs.time_nsec, 1);
1231 assert_eq!(abs.time_sec, 3);
1232 }
1233
1234 #[test]
1235 fn test_abstime_add()
1236 {
1237 let mut abs = AbsoluteTime::new_time(1, 999_999_999);
1238
1239 abs += RelativeTime::new_time(0, 1);
1240
1241 assert_eq!(abs.time_nsec, 0);
1242 assert_eq!(abs.time_sec, 2);
1243
1244 abs += RelativeTime::new_time(1, 1);
1245
1246 assert_eq!(abs.time_nsec, 1);
1247 assert_eq!(abs.time_sec, 3);
1248
1249 abs += RelativeTime::new_time(0, 999_999_999);
1250
1251 assert_eq!(abs.time_nsec, 0);
1252 assert_eq!(abs.time_sec, 4);
1253
1254 abs -= RelativeTime::new_time(0, 999_999_999);
1255
1256 assert_eq!(abs.time_nsec, 1);
1257 assert_eq!(abs.time_sec, 3);
1258
1259 abs -= RelativeTime::new_time(0, 1);
1260
1261 assert_eq!(abs.time_nsec, 0);
1262 assert_eq!(abs.time_sec, 3);
1263
1264 abs -= RelativeTime::new_time(0, 500_000_000);
1265
1266 assert_eq!(abs.time_nsec, 500_000_000);
1267 assert_eq!(abs.time_sec, 2);
1268
1269 abs -= RelativeTime::new_time(0, 400_000_000);
1270
1271 assert_eq!(abs.time_nsec, 100_000_000);
1272 assert_eq!(abs.time_sec, 2);
1273
1274 abs -= RelativeTime::new_time(1, 200_000_000);
1275
1276 assert_eq!(abs.time_nsec, 900_000_000);
1277 assert_eq!(abs.time_sec, 0);
1278 }
1279}