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