1use std::{
4 fmt,
5 io::{self, prelude::*},
6 sync::LazyLock,
7 time::Duration,
8};
9
10use crate::{ffi, prelude::*};
11use glib::translate::*;
12
13use super::{
14 Format, FormattedValue, FormattedValueError, FormattedValueFullRange, FormattedValueIntrinsic,
15 FormattedValueNoneBuilder, GenericFormattedValue, Signed, SpecificFormattedValue,
16 SpecificFormattedValueFullRange, SpecificFormattedValueIntrinsic,
17};
18
19const TRY_FROM_FLOAT_SECS_ERROR_MSG: &str =
20 "can not convert float seconds to ClockTime: value is either negative, too big or NaN";
21
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct TryFromFloatSecsError;
24
25impl fmt::Display for TryFromFloatSecsError {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 f.write_str(TRY_FROM_FLOAT_SECS_ERROR_MSG)
28 }
29}
30
31impl std::error::Error for TryFromFloatSecsError {}
32
33#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
69pub struct ClockTime(u64);
70
71impl ClockTime {
72 #[doc(alias = "GST_SECOND")]
73 pub const SECOND: ClockTime = ClockTime(1_000_000_000);
74 #[doc(alias = "GST_MSECOND")]
75 pub const MSECOND: ClockTime = ClockTime(1_000_000);
76 #[doc(alias = "GST_USECOND")]
77 pub const USECOND: ClockTime = ClockTime(1_000);
78 #[doc(alias = "GST_NSECOND")]
79 pub const NSECOND: ClockTime = ClockTime(1);
80 pub const MAX: ClockTime = ClockTime(ffi::GST_CLOCK_TIME_NONE - 1);
82}
83
84pub const UNIX_TO_NTP_TIME_OFFSET: ClockTime =
91 ClockTime::from_seconds(crate::UNIX_TO_NTP_TIME_OFFSET_SECONDS);
92
93pub static NTP_TO_PTP_TIME_OFFSET: LazyLock<ClockTime> =
98 LazyLock::new(|| ClockTime::from_seconds(*crate::NTP_TO_PTP_TIME_OFFSET_SECONDS));
99
100pub static UTC_TO_TAI_LEAP_SECONDS: LazyLock<ClockTime> =
105 LazyLock::new(|| ClockTime::from_seconds(*crate::UTC_TO_TAI_LEAP_SECONDS));
106
107pub static UNIX_TO_PTP_TIME_OFFSET: LazyLock<ClockTime> =
112 LazyLock::new(|| ClockTime::from_seconds(*crate::UNIX_TO_PTP_TIME_OFFSET_SECONDS));
113
114impl ClockTime {
115 #[inline]
116 pub const fn hours(self) -> u64 {
117 self.0 / Self::SECOND.0 / 60 / 60
118 }
119
120 #[inline]
121 pub const fn minutes(self) -> u64 {
122 self.0 / Self::SECOND.0 / 60
123 }
124
125 #[inline]
126 pub const fn seconds(self) -> u64 {
127 self.0 / Self::SECOND.0
128 }
129
130 #[inline]
131 pub fn seconds_f32(self) -> f32 {
132 self.0 as f32 / Self::SECOND.0 as f32
133 }
134
135 #[inline]
136 pub fn seconds_f64(self) -> f64 {
137 self.0 as f64 / Self::SECOND.0 as f64
138 }
139
140 #[inline]
141 pub const fn mseconds(self) -> u64 {
142 self.0 / Self::MSECOND.0
143 }
144
145 #[inline]
146 pub const fn useconds(self) -> u64 {
147 self.0 / Self::USECOND.0
148 }
149
150 #[inline]
151 pub const fn nseconds(self) -> u64 {
152 self.0
153 }
154
155 #[track_caller]
162 #[inline]
163 pub const fn from_seconds(seconds: u64) -> Self {
164 skip_assert_initialized!();
165 ClockTime(
166 seconds
167 .checked_mul(Self::SECOND.0)
168 .expect("Out of `ClockTime` range"),
169 )
170 }
171
172 #[inline]
178 pub fn try_from_seconds_f32(seconds: f32) -> Result<Self, TryFromFloatSecsError> {
179 skip_assert_initialized!();
180
181 let dur = Duration::try_from_secs_f32(seconds).map_err(|_| TryFromFloatSecsError)?;
182 ClockTime::try_from(dur).map_err(|_| TryFromFloatSecsError)
183 }
184
185 #[track_caller]
193 #[inline]
194 pub fn from_seconds_f32(seconds: f32) -> Self {
195 skip_assert_initialized!();
196
197 Self::try_from_seconds_f32(seconds).expect(TRY_FROM_FLOAT_SECS_ERROR_MSG)
198 }
199
200 #[inline]
206 pub fn try_from_seconds_f64(seconds: f64) -> Result<Self, TryFromFloatSecsError> {
207 skip_assert_initialized!();
208
209 let dur = Duration::try_from_secs_f64(seconds).map_err(|_| TryFromFloatSecsError)?;
210 ClockTime::try_from(dur).map_err(|_| TryFromFloatSecsError)
211 }
212
213 #[track_caller]
221 #[inline]
222 pub fn from_seconds_f64(seconds: f64) -> Self {
223 skip_assert_initialized!();
224
225 Self::try_from_seconds_f64(seconds).expect(TRY_FROM_FLOAT_SECS_ERROR_MSG)
226 }
227
228 #[track_caller]
235 #[inline]
236 pub const fn from_mseconds(mseconds: u64) -> Self {
237 skip_assert_initialized!();
238 ClockTime(
239 mseconds
240 .checked_mul(Self::MSECOND.0)
241 .expect("Out of `ClockTime` range"),
242 )
243 }
244
245 #[track_caller]
252 #[inline]
253 pub const fn from_useconds(useconds: u64) -> Self {
254 skip_assert_initialized!();
255 ClockTime(
256 useconds
257 .checked_mul(Self::USECOND.0)
258 .expect("Out of `ClockTime` range"),
259 )
260 }
261
262 #[track_caller]
270 #[inline]
271 pub const fn from_nseconds(nseconds: u64) -> Self {
272 skip_assert_initialized!();
273 assert!(
274 nseconds != ffi::GST_CLOCK_TIME_NONE,
275 "Attempt to build a `ClockTime` with value `GST_CLOCK_TIME_NONE`",
276 );
277 ClockTime(nseconds * Self::NSECOND.0)
278 }
279}
280
281impl Signed<ClockTime> {
282 #[inline]
285 pub fn nseconds(self) -> Signed<u64> {
286 match self {
287 Signed::Positive(val) => Signed::Positive(val.nseconds()),
288 Signed::Negative(val) => Signed::Negative(val.nseconds()),
289 }
290 }
291
292 #[inline]
295 pub fn from_nseconds(val: Signed<u64>) -> Self {
296 skip_assert_initialized!();
297 match val {
298 Signed::Positive(val) => Signed::Positive(ClockTime::from_nseconds(val)),
299 Signed::Negative(val) => Signed::Negative(ClockTime::from_nseconds(val)),
300 }
301 }
302
303 #[inline]
306 pub fn useconds(self) -> Signed<u64> {
307 match self {
308 Signed::Positive(val) => Signed::Positive(val.useconds()),
309 Signed::Negative(val) => Signed::Negative(val.useconds()),
310 }
311 }
312
313 #[inline]
316 pub fn from_useconds(val: Signed<u64>) -> Self {
317 skip_assert_initialized!();
318 match val {
319 Signed::Positive(val) => Signed::Positive(ClockTime::from_useconds(val)),
320 Signed::Negative(val) => Signed::Negative(ClockTime::from_useconds(val)),
321 }
322 }
323
324 #[inline]
327 pub fn mseconds(self) -> Signed<u64> {
328 match self {
329 Signed::Positive(val) => Signed::Positive(val.mseconds()),
330 Signed::Negative(val) => Signed::Negative(val.mseconds()),
331 }
332 }
333
334 #[inline]
337 pub fn from_mseconds(val: Signed<u64>) -> Self {
338 skip_assert_initialized!();
339 match val {
340 Signed::Positive(val) => Signed::Positive(ClockTime::from_mseconds(val)),
341 Signed::Negative(val) => Signed::Negative(ClockTime::from_mseconds(val)),
342 }
343 }
344
345 #[inline]
348 pub fn seconds(self) -> Signed<u64> {
349 match self {
350 Signed::Positive(val) => Signed::Positive(val.seconds()),
351 Signed::Negative(val) => Signed::Negative(val.seconds()),
352 }
353 }
354
355 #[inline]
358 pub fn seconds_f32(self) -> f32 {
359 match self {
360 Signed::Positive(val) => val.seconds_f32(),
361 Signed::Negative(val) => -val.seconds_f32(),
362 }
363 }
364
365 #[inline]
368 pub fn seconds_f64(self) -> f64 {
369 match self {
370 Signed::Positive(val) => val.seconds_f64(),
371 Signed::Negative(val) => -val.seconds_f64(),
372 }
373 }
374
375 #[inline]
378 pub fn from_seconds(val: Signed<u64>) -> Self {
379 skip_assert_initialized!();
380 match val {
381 Signed::Positive(val) => Signed::Positive(ClockTime::from_seconds(val)),
382 Signed::Negative(val) => Signed::Negative(ClockTime::from_seconds(val)),
383 }
384 }
385
386 #[inline]
392 pub fn try_from_seconds_f32(seconds: f32) -> Result<Self, TryFromFloatSecsError> {
393 skip_assert_initialized!();
394
395 ClockTime::try_from_seconds_f32(seconds.abs()).map(|ct| {
396 if seconds.is_sign_positive() {
397 Signed::Positive(ct)
398 } else {
399 Signed::Negative(ct)
400 }
401 })
402 }
403
404 #[track_caller]
412 #[inline]
413 pub fn from_seconds_f32(seconds: f32) -> Self {
414 skip_assert_initialized!();
415
416 Self::try_from_seconds_f32(seconds).expect(TRY_FROM_FLOAT_SECS_ERROR_MSG)
417 }
418
419 #[inline]
425 pub fn try_from_seconds_f64(seconds: f64) -> Result<Self, TryFromFloatSecsError> {
426 skip_assert_initialized!();
427
428 ClockTime::try_from_seconds_f64(seconds.abs()).map(|ct| {
429 if seconds.is_sign_positive() {
430 Signed::Positive(ct)
431 } else {
432 Signed::Negative(ct)
433 }
434 })
435 }
436
437 #[track_caller]
445 #[inline]
446 pub fn from_seconds_f64(seconds: f64) -> Self {
447 skip_assert_initialized!();
448
449 Self::try_from_seconds_f64(seconds).expect(TRY_FROM_FLOAT_SECS_ERROR_MSG)
450 }
451}
452
453impl_format_value_traits!(ClockTime, Time, Time, u64);
454option_glib_newtype_from_to!(ClockTime, ffi::GST_CLOCK_TIME_NONE);
455
456pub trait TimeFormatConstructor {
460 fn nseconds(self) -> ClockTime;
463
464 fn useconds(self) -> ClockTime;
467
468 fn mseconds(self) -> ClockTime;
471
472 fn seconds(self) -> ClockTime;
475
476 fn minutes(self) -> ClockTime;
479
480 fn hours(self) -> ClockTime;
483}
484
485impl TimeFormatConstructor for u64 {
486 #[track_caller]
487 #[inline]
488 fn nseconds(self) -> ClockTime {
489 ClockTime::from_nseconds(self)
490 }
491
492 #[track_caller]
493 #[inline]
494 fn useconds(self) -> ClockTime {
495 ClockTime::from_useconds(self)
496 }
497
498 #[track_caller]
499 #[inline]
500 fn mseconds(self) -> ClockTime {
501 ClockTime::from_mseconds(self)
502 }
503
504 #[track_caller]
505 #[inline]
506 fn seconds(self) -> ClockTime {
507 ClockTime::from_seconds(self)
508 }
509
510 #[track_caller]
511 #[inline]
512 fn minutes(self) -> ClockTime {
513 ClockTime::from_seconds(self * 60)
514 }
515
516 #[track_caller]
517 #[inline]
518 fn hours(self) -> ClockTime {
519 ClockTime::from_seconds(self * 60 * 60)
520 }
521}
522
523impl glib::value::ValueType for ClockTime {
524 type Type = Self;
525}
526
527pub enum ClockTimeValueTypeOrNoneChecker {}
528
529unsafe impl glib::value::ValueTypeChecker for ClockTimeValueTypeOrNoneChecker {
530 type Error = glib::value::ValueTypeMismatchOrNoneError<glib::value::ValueTypeMismatchError>;
531
532 #[inline]
533 fn check(value: &glib::Value) -> Result<(), Self::Error> {
534 skip_assert_initialized!();
535 glib::value::GenericValueTypeChecker::<ClockTime>::check(value)?;
536
537 let gct = unsafe { glib::gobject_ffi::g_value_get_uint64(value.to_glib_none().0) };
538 if gct == ffi::GST_CLOCK_TIME_NONE {
539 return Err(glib::value::ValueTypeMismatchOrNoneError::UnexpectedNone);
540 }
541
542 Ok(())
543 }
544}
545
546unsafe impl glib::value::FromValue<'_> for ClockTime {
547 type Checker = ClockTimeValueTypeOrNoneChecker;
548
549 #[inline]
550 unsafe fn from_value(value: &glib::Value) -> ClockTime {
551 unsafe {
552 skip_assert_initialized!();
553 ClockTime(glib::gobject_ffi::g_value_get_uint64(
554 value.to_glib_none().0,
555 ))
556 }
557 }
558}
559
560impl glib::value::ToValue for ClockTime {
561 #[inline]
562 fn to_value(&self) -> glib::Value {
563 let mut value = glib::Value::for_value_type::<ClockTime>();
564 let gct = self.into_glib();
565 if gct == ffi::GST_CLOCK_TIME_NONE {
566 crate::warning!(
567 crate::CAT_RUST,
568 "converting a defined `ClockTime` with value `GST_CLOCK_TIME_NONE` to `Value`, this is probably not what you wanted.",
569 );
570 }
571 unsafe { glib::gobject_ffi::g_value_set_uint64(value.to_glib_none_mut().0, gct) }
572 value
573 }
574
575 #[inline]
576 fn value_type(&self) -> glib::Type {
577 Self::static_type()
578 }
579}
580
581impl glib::value::ToValueOptional for ClockTime {
582 #[inline]
583 fn to_value_optional(opt: Option<&Self>) -> glib::Value {
584 skip_assert_initialized!();
585 let mut value = glib::Value::for_value_type::<ClockTime>();
586 let inner = opt.map(|inner| inner.0).unwrap_or(ffi::GST_CLOCK_TIME_NONE);
587 unsafe { glib::gobject_ffi::g_value_set_uint64(value.to_glib_none_mut().0, inner) };
588
589 value
590 }
591}
592
593impl From<ClockTime> for glib::Value {
594 #[inline]
595 fn from(v: ClockTime) -> glib::Value {
596 glib::value::ToValue::to_value(&v)
597 }
598}
599
600#[doc(hidden)]
601impl StaticType for ClockTime {
602 #[inline]
603 fn static_type() -> glib::Type {
604 <u64 as StaticType>::static_type()
605 }
606}
607
608impl HasParamSpec for ClockTime {
609 type ParamSpec = glib::ParamSpecUInt64;
610 type SetValue = Self;
611 type BuilderFn = fn(&str) -> glib::ParamSpecUInt64Builder;
612
613 fn param_spec_builder() -> Self::BuilderFn {
614 Self::ParamSpec::builder
615 }
616}
617
618#[derive(Debug)]
619pub struct DurationError;
620
621impl fmt::Display for DurationError {
622 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
623 write!(fmt, "out of range conversion from Duration attempted")
624 }
625}
626
627impl std::error::Error for DurationError {}
628
629impl TryFrom<Duration> for ClockTime {
630 type Error = DurationError;
631
632 #[inline]
633 fn try_from(d: Duration) -> Result<Self, Self::Error> {
634 skip_assert_initialized!();
635
636 let nanos = d.as_nanos();
637
638 if nanos >= u64::MAX as u128 {
640 return Err(DurationError);
641 }
642
643 Ok(ClockTime::from_nseconds(nanos as u64))
644 }
645}
646
647impl From<ClockTime> for Duration {
648 #[inline]
649 fn from(t: ClockTime) -> Self {
650 skip_assert_initialized!();
651
652 Duration::from_nanos(t.nseconds())
653 }
654}
655
656impl_common_ops_for_newtype_uint!(ClockTime, u64);
657impl_signed_div_mul!(ClockTime, u64);
658impl_signed_int_into_signed!(ClockTime, u64);
659
660enum Sign {
663 Undefined,
666
667 NonNegative,
670
671 #[allow(dead_code)]
673 Negative,
676}
677
678fn pad_clocktime(f: &mut fmt::Formatter<'_>, sign: Sign, buf: &str) -> fmt::Result {
688 skip_assert_initialized!();
689 use std::fmt::{Alignment, Write};
690
691 use self::Sign::*;
692
693 let sign_aware_zero_pad = f.sign_aware_zero_pad();
698 let fill_char = match sign {
699 Undefined if sign_aware_zero_pad => '-', _ if sign_aware_zero_pad => '0', _ => f.fill(), };
703
704 let sign_plus = f.sign_plus();
706 let sign_char = match sign {
707 Undefined if sign_plus => Some(fill_char), NonNegative if sign_plus => Some('+'), Negative => Some('-'), _ => None, };
712
713 let width = buf.len() + sign_char.map_or(0, |_| 1);
715
716 let padding = f.width().unwrap_or(0).saturating_sub(width);
719
720 let align = f.align().unwrap_or(Alignment::Right);
722 let (pre_padding, zero_padding, post_padding) = match align {
723 _ if sign_aware_zero_pad => (0, padding, 0), Alignment::Left => (0, 0, padding), Alignment::Right => (padding, 0, 0), Alignment::Center => (padding / 2, 0, padding.div_ceil(2)),
730 };
731
732 for _ in 0..pre_padding {
735 f.write_char(fill_char)?; }
737 if let Some(c) = sign_char {
738 f.write_char(c)?; }
740 for _ in 0..zero_padding {
741 f.write_char(fill_char)?; }
743 f.write_str(buf)?; for _ in 0..post_padding {
745 f.write_char(fill_char)?; }
747
748 Ok(())
749}
750
751fn write_clocktime<W: io::Write>(
754 mut writer: W,
755 clocktime: Option<ClockTime>,
756 precision: usize,
757) -> io::Result<()> {
758 skip_assert_initialized!();
759 let precision = std::cmp::min(9, precision);
760
761 if let Some(ns) = clocktime.map(ClockTime::nseconds) {
762 let (s, ns) = num_integer::div_rem(ns, 1_000_000_000);
764 let (m, s) = num_integer::div_rem(s, 60);
765 let (h, m) = num_integer::div_rem(m, 60);
766
767 write!(writer, "{h}:{m:02}:{s:02}")?;
769
770 if precision > 0 {
771 let mut buf = [0u8; 9];
774 write!(&mut buf[..], "{ns:09}").unwrap();
775 let buf_str = std::str::from_utf8(&buf[..]).unwrap();
776
777 write!(writer, ".{buf_str:.precision$}")?;
779 }
780 } else {
781 write!(writer, "--:--:--")?;
785
786 if precision > 0 {
787 write!(writer, ".{:->p$}", "", p = precision)?;
789 }
790 }
791
792 Ok(())
793}
794
795fn fmt_opt_clock_time(ct: Option<ClockTime>, f: &mut fmt::Formatter) -> fmt::Result {
796 skip_assert_initialized!();
797 let precision = f.precision().unwrap_or(9);
798
799 const MAX_SIZE: usize = "5124095:34:33.709551614".len();
801
802 let mut buf = [0u8; MAX_SIZE];
804 let mut cursor = io::Cursor::new(&mut buf[..]);
805 write_clocktime(&mut cursor, ct, precision).unwrap();
806 let pos = cursor.position() as usize;
807 let buf_str = std::str::from_utf8(&buf[..pos]).unwrap();
808
809 let sign = if ct.is_some() {
810 Sign::NonNegative
811 } else {
812 Sign::Undefined
813 };
814
815 pad_clocktime(f, sign, buf_str)
816}
817
818impl fmt::Display for ClockTime {
819 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
820 fmt_opt_clock_time(Some(*self), f)
821 }
822}
823
824impl fmt::Debug for ClockTime {
825 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
826 fmt::Display::fmt(self, f)
827 }
828}
829
830pub struct DisplayableOptClockTime(Option<ClockTime>);
831
832impl fmt::Display for DisplayableOptClockTime {
833 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
834 fmt_opt_clock_time(self.0, f)
835 }
836}
837
838impl fmt::Debug for DisplayableOptClockTime {
839 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
840 fmt::Display::fmt(self, f)
841 }
842}
843
844impl crate::utils::Displayable for Option<ClockTime> {
845 type DisplayImpl = DisplayableOptClockTime;
846
847 fn display(self) -> DisplayableOptClockTime {
848 DisplayableOptClockTime(self)
849 }
850}
851
852impl crate::utils::Displayable for ClockTime {
853 type DisplayImpl = ClockTime;
854
855 fn display(self) -> ClockTime {
856 self
857 }
858}
859
860impl std::iter::Sum for ClockTime {
861 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
862 skip_assert_initialized!();
863 iter.fold(ClockTime::ZERO, |a, b| a + b)
864 }
865}
866
867#[cfg(test)]
868mod tests {
869 use opt_ops::prelude::*;
870
871 use super::*;
872 use crate::format::{Signed, UnsignedIntoSigned};
873
874 const CT_1: ClockTime = ClockTime::from_nseconds(1);
875 const CT_2: ClockTime = ClockTime::from_nseconds(2);
876 const CT_3: ClockTime = ClockTime::from_nseconds(3);
877 const CT_10: ClockTime = ClockTime::from_nseconds(10);
878 const CT_20: ClockTime = ClockTime::from_nseconds(20);
879 const CT_30: ClockTime = ClockTime::from_nseconds(30);
880
881 const P_CT_0: Signed<ClockTime> = Signed::Positive(ClockTime::ZERO);
882 const P_CT_NONE: Option<Signed<ClockTime>> = None;
883 const P_CT_1: Signed<ClockTime> = Signed::Positive(ClockTime::from_nseconds(1));
884 const P_CT_2: Signed<ClockTime> = Signed::Positive(ClockTime::from_nseconds(2));
885 const P_CT_3: Signed<ClockTime> = Signed::Positive(ClockTime::from_nseconds(3));
886 const N_CT_1: Signed<ClockTime> = Signed::Negative(ClockTime::from_nseconds(1));
887 const N_CT_2: Signed<ClockTime> = Signed::Negative(ClockTime::from_nseconds(2));
888 const N_CT_3: Signed<ClockTime> = Signed::Negative(ClockTime::from_nseconds(3));
889
890 #[test]
891 fn opt_time_clock() {
892 assert_eq!(CT_1.into_glib(), 1);
893 assert_eq!(Some(CT_1).into_glib(), 1);
894 assert_eq!(ClockTime::NONE.into_glib(), ffi::GST_CLOCK_TIME_NONE);
895
896 let ct_1_from: ClockTime = unsafe { try_from_glib(1u64) }.unwrap();
897 assert_eq!(ct_1_from, CT_1);
898
899 let opt_ct_some: Option<ClockTime> = unsafe { from_glib(1u64) };
900 assert_eq!(opt_ct_some, Some(CT_1));
901
902 let ct_none: Option<ClockTime> = unsafe { from_glib(ffi::GST_CLOCK_TIME_NONE) };
903 assert_eq!(ct_none, None);
904 }
905
906 #[test]
907 #[allow(clippy::eq_op, clippy::op_ref)]
908 fn ops() {
909 assert_eq!(CT_10 + CT_20, CT_30);
910 assert_eq!(CT_30 - CT_20, CT_10);
911 assert_eq!(CT_30 - CT_30, ClockTime::ZERO);
912 assert_eq!(CT_10 * 3, CT_30);
913 assert_eq!(3 * CT_10, CT_30);
914 assert_eq!(CT_20 / 2, CT_10);
915 assert_eq!(CT_20 / CT_2, 10);
916 assert_eq!(CT_30.nseconds(), 30);
917
918 assert_eq!(P_CT_1 + P_CT_2, P_CT_3);
919 assert_eq!(P_CT_3 + N_CT_2, P_CT_1);
920 assert_eq!(P_CT_2 + N_CT_3, N_CT_1);
921 assert_eq!(N_CT_3 + P_CT_1, N_CT_2);
922 assert_eq!(N_CT_2 + P_CT_3, P_CT_1);
923 assert_eq!(N_CT_2 + N_CT_1, N_CT_3);
924
925 assert_eq!(CT_1 + P_CT_2, P_CT_3);
926 assert_eq!(P_CT_1 + CT_2, P_CT_3);
927 assert_eq!(CT_3 + N_CT_1, P_CT_2);
928 assert_eq!(N_CT_1 + CT_2, P_CT_1);
929
930 assert_eq!(P_CT_3 - P_CT_2, P_CT_1);
931 assert_eq!(P_CT_2 - P_CT_3, N_CT_1);
932 assert_eq!(P_CT_2 - N_CT_1, P_CT_3);
933 assert_eq!(N_CT_2 - P_CT_1, N_CT_3);
934 assert_eq!(N_CT_3 - N_CT_1, N_CT_2);
935
936 assert_eq!(CT_3 - P_CT_2, P_CT_1);
937 assert_eq!(P_CT_3 - CT_2, P_CT_1);
938 assert_eq!(N_CT_2 - CT_1, N_CT_3);
939 assert_eq!(CT_2 - N_CT_1, P_CT_3);
940
941 assert_eq!(P_CT_1 * 2i64, P_CT_2);
942 assert_eq!(P_CT_1 * -2i64, N_CT_2);
943 assert_eq!(N_CT_1 * 2i64, N_CT_2);
944 assert_eq!(N_CT_1 * -2i64, P_CT_2);
945
946 assert_eq!(2i64 * P_CT_1, P_CT_2);
947 assert_eq!(-2i64 * P_CT_1, N_CT_2);
948
949 assert_eq!(P_CT_1 * 2u64, P_CT_2);
950 assert_eq!(N_CT_1 * 2u64, N_CT_2);
951
952 assert_eq!(P_CT_2 / 2i64, P_CT_1);
953 assert_eq!(P_CT_2 / -2i64, N_CT_1);
954 assert_eq!(N_CT_2 / 2i64, N_CT_1);
955 assert_eq!(N_CT_2 / -2i64, P_CT_1);
956
957 assert_eq!(P_CT_2 / N_CT_2, Signed::Negative(1));
958
959 assert_eq!(P_CT_2 / 2u64, P_CT_1);
960 assert_eq!(N_CT_2 / 2u64, N_CT_1);
961
962 assert_eq!(P_CT_3 % 2i64, P_CT_1);
963 assert_eq!(P_CT_3 % -2i64, P_CT_1);
964 assert_eq!(N_CT_3 % 2i64, N_CT_1);
965 assert_eq!(N_CT_3 % -2i64, N_CT_1);
966
967 assert_eq!(N_CT_3 % N_CT_2, N_CT_1);
968
969 assert_eq!(P_CT_3 % 2u64, P_CT_1);
970 assert_eq!(N_CT_3 % 2u64, N_CT_1);
971 }
972
973 #[test]
974 fn checked_ops() {
975 assert_eq!(CT_1.checked_add(CT_1), Some(CT_2));
976 assert_eq!(P_CT_1.checked_add(P_CT_2), Some(P_CT_3));
977 assert_eq!(P_CT_3.checked_add(N_CT_2), Some(P_CT_1));
978 assert_eq!(P_CT_2.checked_add(N_CT_3), Some(N_CT_1));
979 assert_eq!(N_CT_3.checked_add(P_CT_1), Some(N_CT_2));
980 assert_eq!(N_CT_2.checked_add(P_CT_3), Some(P_CT_1));
981 assert_eq!(N_CT_2.checked_add(N_CT_1), Some(N_CT_3));
982
983 assert_eq!(CT_1.opt_checked_add(CT_1), Ok(Some(CT_2)));
984 assert_eq!(CT_1.opt_checked_add(Some(CT_1)), Ok(Some(CT_2)));
985 assert_eq!(Some(CT_1).opt_checked_add(Some(CT_1)), Ok(Some(CT_2)));
986 assert_eq!(CT_1.opt_checked_add(ClockTime::NONE), Ok(None));
987 assert_eq!(Some(CT_1).opt_checked_add(ClockTime::NONE), Ok(None));
988
989 assert_eq!(CT_1.opt_checked_add(P_CT_1), Ok(Some(P_CT_2)));
990 assert_eq!(N_CT_3.opt_checked_add(CT_1), Ok(Some(N_CT_2)));
991
992 assert!(ClockTime::MAX.checked_add(CT_1).is_none());
993 assert_eq!(
994 ClockTime::MAX.opt_checked_add(Some(CT_1)),
995 Err(opt_ops::Error::Overflow)
996 );
997
998 assert_eq!(P_CT_1.opt_checked_add(P_CT_1), Ok(Some(P_CT_2)));
999 assert_eq!(P_CT_1.opt_checked_add(Some(N_CT_2)), Ok(Some(N_CT_1)));
1000 assert_eq!(Some(P_CT_1).opt_checked_add(Some(P_CT_1)), Ok(Some(P_CT_2)));
1001 assert_eq!(P_CT_1.opt_checked_add(ClockTime::NONE), Ok(None));
1002 assert_eq!(Some(N_CT_1).opt_checked_add(ClockTime::NONE), Ok(None));
1003
1004 assert_eq!(
1005 ClockTime::MAX.into_positive().opt_checked_add(Some(P_CT_1)),
1006 Err(opt_ops::Error::Overflow)
1007 );
1008
1009 assert_eq!(CT_2.checked_sub(CT_1), Some(CT_1));
1010 assert_eq!(P_CT_3.checked_sub(P_CT_2), Some(P_CT_1));
1011 assert_eq!(P_CT_2.checked_sub(P_CT_3), Some(N_CT_1));
1012 assert_eq!(P_CT_2.checked_sub(N_CT_1), Some(P_CT_3));
1013 assert_eq!(N_CT_2.checked_sub(P_CT_1), Some(N_CT_3));
1014 assert_eq!(N_CT_3.checked_sub(N_CT_1), Some(N_CT_2));
1015 assert_eq!(N_CT_2.checked_sub(N_CT_3), Some(P_CT_1));
1016
1017 assert_eq!(CT_2.opt_checked_sub(CT_1), Ok(Some(CT_1)));
1018 assert_eq!(CT_2.opt_checked_sub(Some(CT_1)), Ok(Some(CT_1)));
1019 assert_eq!(Some(CT_2).opt_checked_sub(CT_1), Ok(Some(CT_1)));
1020 assert_eq!(Some(CT_2).opt_checked_sub(Some(CT_1)), Ok(Some(CT_1)));
1021 assert_eq!(CT_2.opt_checked_sub(ClockTime::NONE), Ok(None));
1022 assert_eq!(Some(CT_2).opt_checked_sub(ClockTime::NONE), Ok(None));
1023
1024 assert_eq!(P_CT_2.opt_checked_sub(CT_1), Ok(Some(P_CT_1)));
1025 assert_eq!(N_CT_2.opt_checked_sub(CT_1), Ok(Some(N_CT_3)));
1026
1027 assert!(CT_1.checked_sub(CT_2).is_none());
1028 assert_eq!(
1029 Some(CT_1).opt_checked_sub(CT_2),
1030 Err(opt_ops::Error::Overflow)
1031 );
1032
1033 assert_eq!(P_CT_2.opt_checked_sub(Some(N_CT_1)), Ok(Some(P_CT_3)));
1034 assert_eq!(Some(N_CT_2).opt_checked_sub(P_CT_1), Ok(Some(N_CT_3)));
1035
1036 assert_eq!(CT_1.checked_mul(2), Some(CT_2));
1037 assert_eq!(Some(CT_1).opt_checked_mul(2), Ok(Some(CT_2)));
1038 assert_eq!(1u64.opt_checked_mul(Some(CT_2)), Ok(Some(CT_2)));
1039 assert_eq!(P_CT_1.checked_mul(2), Some(P_CT_2));
1040 assert_eq!(P_CT_1.checked_mul(-2), Some(N_CT_2));
1041 assert_eq!(N_CT_1.checked_mul(2), Some(N_CT_2));
1042 assert_eq!(N_CT_1.checked_mul(-2), Some(P_CT_2));
1043
1044 assert_eq!(Some(P_CT_1).opt_checked_mul(-2i64), Ok(Some(N_CT_2)));
1045 assert_eq!(N_CT_1.opt_checked_mul(2u64), Ok(Some(N_CT_2)));
1046
1047 assert_eq!((-2i64).opt_checked_mul(Some(P_CT_1)), Ok(Some(N_CT_2)));
1048
1049 assert_eq!(P_CT_1.checked_mul_unsigned(2u64), Some(P_CT_2));
1050 assert_eq!(N_CT_1.checked_mul_unsigned(2u64), Some(N_CT_2));
1051
1052 assert_eq!(CT_3.checked_div(3), Some(CT_1));
1053 assert_eq!(P_CT_3.checked_div(3), Some(P_CT_1));
1054 assert_eq!(P_CT_3.checked_div(-3), Some(N_CT_1));
1055 assert_eq!(N_CT_3.checked_div(3), Some(N_CT_1));
1056 assert_eq!(N_CT_3.checked_div(-3), Some(P_CT_1));
1057
1058 assert_eq!(Some(CT_3).opt_checked_div(CT_3), Ok(Some(1)));
1059
1060 assert_eq!(Some(P_CT_3).opt_checked_div(-3i64), Ok(Some(N_CT_1)));
1061 assert_eq!(N_CT_3.opt_checked_div(3u64), Ok(Some(N_CT_1)));
1062
1063 assert_eq!(P_CT_3.checked_div_unsigned(3u64), Some(P_CT_1));
1064 assert_eq!(N_CT_3.checked_div_unsigned(3u64), Some(N_CT_1));
1065 }
1066
1067 #[test]
1068 fn overflowing_ops() {
1069 assert_eq!(CT_1.overflowing_add(CT_2), (CT_3, false));
1070 assert_eq!(CT_1.opt_overflowing_add(Some(CT_2)), Some((CT_3, false)));
1071 assert_eq!(Some(CT_1).opt_overflowing_add(CT_2), Some((CT_3, false)));
1072 assert_eq!(
1073 Some(CT_1).opt_overflowing_add(Some(CT_2)),
1074 Some((CT_3, false))
1075 );
1076
1077 assert_eq!(ClockTime::NONE.opt_overflowing_add(CT_2), None);
1078 assert_eq!(CT_1.opt_overflowing_add(ClockTime::NONE), None);
1079
1080 assert_eq!(
1081 ClockTime::MAX.overflowing_add(CT_1),
1082 (ClockTime::ZERO, true)
1083 );
1084 assert_eq!(
1085 Some(ClockTime::MAX).opt_overflowing_add(Some(CT_1)),
1086 Some((ClockTime::ZERO, true)),
1087 );
1088
1089 assert_eq!(CT_3.overflowing_sub(CT_2), (CT_1, false));
1090 assert_eq!(CT_3.opt_overflowing_sub(Some(CT_2)), Some((CT_1, false)));
1091 assert_eq!(Some(CT_3).opt_overflowing_sub(CT_2), Some((CT_1, false)));
1092 assert_eq!(
1093 Some(CT_3).opt_overflowing_sub(Some(CT_2)),
1094 Some((CT_1, false))
1095 );
1096 assert_eq!(
1097 Some(CT_3).opt_overflowing_sub(&Some(CT_2)),
1098 Some((CT_1, false))
1099 );
1100 assert_eq!(ClockTime::NONE.opt_overflowing_sub(CT_2), None);
1101 assert_eq!(CT_2.opt_overflowing_sub(ClockTime::NONE), None);
1102
1103 assert_eq!(CT_1.overflowing_sub(CT_2), (ClockTime::MAX, true));
1104 assert_eq!(
1105 Some(CT_1).opt_overflowing_sub(CT_2),
1106 Some((ClockTime::MAX, true))
1107 );
1108 }
1109
1110 #[test]
1111 fn saturating_ops() {
1112 let p_ct_max: Signed<ClockTime> = ClockTime::MAX.into_positive();
1113 let n_ct_max: Signed<ClockTime> = ClockTime::MAX.into_negative();
1114
1115 assert_eq!(CT_1.saturating_add(CT_2), CT_3);
1116 assert_eq!(P_CT_1.saturating_add(P_CT_2), P_CT_3);
1117 assert_eq!(P_CT_2.saturating_add(N_CT_3), N_CT_1);
1118 assert_eq!(P_CT_3.saturating_add(N_CT_2), P_CT_1);
1119 assert_eq!(N_CT_3.saturating_add(P_CT_1), N_CT_2);
1120 assert_eq!(N_CT_2.saturating_add(P_CT_3), P_CT_1);
1121 assert_eq!(N_CT_2.saturating_add(N_CT_1), N_CT_3);
1122
1123 assert_eq!(CT_1.opt_saturating_add(Some(CT_2)), Some(CT_3));
1124 assert_eq!(Some(CT_1).opt_saturating_add(Some(CT_2)), Some(CT_3));
1125 assert_eq!(Some(CT_1).opt_saturating_add(ClockTime::NONE), None);
1126
1127 assert_eq!(P_CT_1.opt_saturating_add(Some(CT_2)), Some(P_CT_3));
1128 assert_eq!(Some(CT_1).opt_saturating_add(P_CT_2), Some(P_CT_3));
1129
1130 assert_eq!(ClockTime::MAX.saturating_add(CT_1), ClockTime::MAX);
1131 assert_eq!(
1132 Some(ClockTime::MAX).opt_saturating_add(Some(CT_1)),
1133 Some(ClockTime::MAX)
1134 );
1135 assert_eq!(p_ct_max.saturating_add(P_CT_1), p_ct_max);
1136
1137 assert_eq!(CT_3.saturating_sub(CT_2), CT_1);
1138 assert_eq!(P_CT_3.saturating_sub(P_CT_2), P_CT_1);
1139 assert_eq!(P_CT_2.saturating_sub(P_CT_3), N_CT_1);
1140 assert_eq!(P_CT_2.saturating_sub(N_CT_1), P_CT_3);
1141 assert_eq!(N_CT_2.saturating_sub(P_CT_1), N_CT_3);
1142 assert_eq!(N_CT_3.saturating_sub(N_CT_1), N_CT_2);
1143 assert_eq!(N_CT_2.saturating_sub(N_CT_3), P_CT_1);
1144
1145 assert_eq!(CT_3.opt_saturating_sub(Some(CT_2)), Some(CT_1));
1146 assert_eq!(Some(CT_3).opt_saturating_sub(Some(CT_2)), Some(CT_1));
1147 assert_eq!(Some(CT_3).opt_saturating_sub(ClockTime::NONE), None);
1148
1149 assert_eq!(P_CT_2.opt_saturating_sub(Some(CT_3)), Some(N_CT_1));
1150 assert_eq!(Some(CT_3).opt_saturating_sub(P_CT_2), Some(P_CT_1));
1151
1152 assert!(CT_1.saturating_sub(CT_2).is_zero());
1153 assert_eq!(P_CT_1.saturating_sub(P_CT_2), N_CT_1);
1154 assert_eq!(
1155 Some(CT_1).opt_saturating_sub(Some(CT_2)),
1156 Some(ClockTime::ZERO)
1157 );
1158
1159 assert_eq!(CT_1.saturating_mul(2), CT_2);
1160 assert_eq!(ClockTime::MAX.saturating_mul(2), ClockTime::MAX);
1161
1162 assert_eq!(P_CT_1.saturating_mul(2), P_CT_2);
1163 assert_eq!(P_CT_1.saturating_mul(-2), N_CT_2);
1164 assert_eq!(N_CT_1.saturating_mul(2), N_CT_2);
1165 assert_eq!(N_CT_1.saturating_mul(-2), P_CT_2);
1166
1167 assert_eq!(Some(N_CT_1).opt_saturating_mul(-2i64), Some(P_CT_2));
1168 assert_eq!((-2i64).opt_saturating_mul(Some(N_CT_1)), Some(P_CT_2));
1169
1170 assert_eq!(P_CT_1.saturating_mul_unsigned(2u64), P_CT_2);
1171 assert_eq!(N_CT_1.saturating_mul_unsigned(2u64), N_CT_2);
1172
1173 assert_eq!(p_ct_max.saturating_mul(2), p_ct_max);
1174 assert_eq!(n_ct_max.saturating_mul(2), n_ct_max);
1175
1176 assert_eq!(Some(2i64).opt_saturating_mul(p_ct_max), Some(p_ct_max));
1177 assert_eq!(2u64.opt_saturating_mul(Some(n_ct_max)), Some(n_ct_max));
1178
1179 assert_eq!(p_ct_max.saturating_mul_unsigned(2u64), p_ct_max);
1180 assert_eq!(n_ct_max.saturating_mul_unsigned(2u64), n_ct_max);
1181 }
1182
1183 #[test]
1184 fn wrapping_ops() {
1185 assert_eq!(CT_1.wrapping_add(CT_2), CT_3);
1186 assert_eq!(CT_1.opt_wrapping_add(CT_2), Some(CT_3));
1187 assert_eq!(Some(CT_1).opt_wrapping_add(CT_2), Some(CT_3));
1188 assert_eq!(Some(CT_1).opt_wrapping_add(Some(CT_2)), Some(CT_3));
1189 assert_eq!(Some(CT_1).opt_wrapping_add(None), None);
1190
1191 assert_eq!(ClockTime::MAX.wrapping_add(CT_1), ClockTime::ZERO);
1192 assert_eq!(
1193 Some(ClockTime::MAX).opt_wrapping_add(Some(CT_1)),
1194 Some(ClockTime::ZERO)
1195 );
1196
1197 assert_eq!(CT_3.wrapping_sub(CT_2), CT_1);
1198 assert_eq!(CT_3.opt_wrapping_sub(CT_2), Some(CT_1));
1199 assert_eq!(Some(CT_3).opt_wrapping_sub(CT_2), Some(CT_1));
1200 assert_eq!(Some(CT_3).opt_wrapping_sub(Some(CT_2)), Some(CT_1));
1201 assert_eq!(Some(CT_3).opt_wrapping_sub(ClockTime::NONE), None);
1202
1203 assert_eq!(CT_1.wrapping_sub(CT_2), ClockTime::MAX);
1204 assert_eq!(
1205 Some(CT_1).opt_wrapping_sub(Some(CT_2)),
1206 Some(ClockTime::MAX)
1207 );
1208 }
1209
1210 #[test]
1211 fn mul_div_ops() {
1212 use muldiv::MulDiv;
1213
1214 assert_eq!(CT_1.mul_div_floor(7, 3), Some(CT_2));
1215
1216 assert_eq!(P_CT_1.mul_div_floor(7u64, 3), Some(P_CT_2));
1217 assert_eq!(P_CT_1.mul_div_floor(-7i64, 3), Some(N_CT_2));
1218 assert_eq!(P_CT_1.mul_div_floor(7i64, -3), Some(N_CT_2));
1219 assert_eq!(P_CT_1.mul_div_floor(-7i64, -3), Some(P_CT_2));
1220
1221 assert_eq!(N_CT_1.mul_div_floor(7u64, 3), Some(N_CT_2));
1222 assert_eq!(N_CT_1.mul_div_floor(-7i64, 3), Some(P_CT_2));
1223 assert_eq!(N_CT_1.mul_div_floor(7i64, -3), Some(P_CT_2));
1224 assert_eq!(N_CT_1.mul_div_floor(-7i64, -3), Some(N_CT_2));
1225
1226 assert_eq!(CT_1.mul_div_round(10, 3), Some(CT_3));
1227 assert_eq!(CT_1.mul_div_round(8, 3), Some(CT_3));
1228
1229 assert_eq!(P_CT_1.mul_div_round(10u64, 3), Some(P_CT_3));
1230 assert_eq!(P_CT_1.mul_div_round(8u64, 3), Some(P_CT_3));
1231 assert_eq!(P_CT_1.mul_div_round(-10i64, 3), Some(N_CT_3));
1232 assert_eq!(P_CT_1.mul_div_round(-8i64, 3), Some(N_CT_3));
1233 assert_eq!(P_CT_1.mul_div_round(10i64, -3), Some(N_CT_3));
1234 assert_eq!(P_CT_1.mul_div_round(-10i64, -3), Some(P_CT_3));
1235
1236 assert_eq!(N_CT_1.mul_div_round(10u64, 3), Some(N_CT_3));
1237 assert_eq!(N_CT_1.mul_div_round(-10i64, 3), Some(P_CT_3));
1238 assert_eq!(N_CT_1.mul_div_round(10i64, -3), Some(P_CT_3));
1239 assert_eq!(N_CT_1.mul_div_round(-10i64, -3), Some(N_CT_3));
1240
1241 assert_eq!(CT_1.mul_div_ceil(7, 3), Some(CT_3));
1242
1243 assert_eq!(P_CT_1.mul_div_ceil(7u64, 3), Some(P_CT_3));
1244 assert_eq!(P_CT_1.mul_div_ceil(-7i64, 3), Some(N_CT_3));
1245 assert_eq!(P_CT_1.mul_div_ceil(7i64, -3), Some(N_CT_3));
1246 assert_eq!(P_CT_1.mul_div_ceil(-7i64, -3), Some(P_CT_3));
1247
1248 assert_eq!(N_CT_1.mul_div_ceil(7u64, 3), Some(N_CT_3));
1249 assert_eq!(N_CT_1.mul_div_ceil(-7i64, 3), Some(P_CT_3));
1250 assert_eq!(N_CT_1.mul_div_ceil(7i64, -3), Some(P_CT_3));
1251 assert_eq!(N_CT_1.mul_div_ceil(-7i64, -3), Some(N_CT_3));
1252 }
1253
1254 #[test]
1255 #[allow(clippy::nonminimal_bool)]
1256 fn comp() {
1257 assert!(ClockTime::ZERO < CT_2);
1258 assert!(Some(ClockTime::ZERO) < Some(CT_2));
1259 assert!(CT_2 < CT_3);
1260 assert!(Some(CT_2) < Some(CT_3));
1261 assert!(ClockTime::ZERO < CT_3);
1262 assert!(Some(ClockTime::ZERO) < Some(CT_3));
1263
1264 assert_eq!(CT_2, CT_2);
1265 assert_ne!(CT_3, CT_2);
1266
1267 assert!(ClockTime::ZERO.into_positive() < P_CT_1);
1268 assert!(ClockTime::ZERO.into_positive() > N_CT_1);
1269 assert!(P_CT_1 < P_CT_2);
1270 assert!(P_CT_1 > N_CT_2);
1271 assert!(N_CT_1 < P_CT_2);
1272 assert!(N_CT_3 < N_CT_2);
1273
1274 assert!(P_CT_1 < CT_2);
1275 assert!(CT_1 < P_CT_2);
1276 assert!(N_CT_2 < CT_1);
1277 assert!(CT_1 > N_CT_2);
1278
1279 assert_eq!(CT_2, P_CT_2);
1280 assert_ne!(N_CT_3, CT_3);
1281
1282 assert_eq!(Some(CT_2).opt_lt(Some(CT_3)), Some(true));
1283 assert_eq!(Some(CT_3).opt_lt(CT_2), Some(false));
1284 assert_eq!(Some(CT_2).opt_le(Some(CT_3)), Some(true));
1285 assert_eq!(Some(CT_3).opt_le(CT_3), Some(true));
1286
1287 assert_eq!(Some(P_CT_2).opt_lt(Some(P_CT_3)), Some(true));
1288 assert_eq!(Some(P_CT_3).opt_lt(P_CT_2), Some(false));
1289 assert_eq!(Some(P_CT_2).opt_le(Some(P_CT_3)), Some(true));
1290 assert_eq!(Some(P_CT_3).opt_le(P_CT_3), Some(true));
1291
1292 assert_eq!(Some(P_CT_0).opt_lt(P_CT_NONE), None);
1293 assert_eq!(P_CT_NONE.opt_lt(P_CT_0), None);
1294
1295 assert_eq!(Some(N_CT_3).opt_lt(Some(N_CT_2)), Some(true));
1296 assert_eq!(Some(N_CT_2).opt_lt(N_CT_3), Some(false));
1297 assert_eq!(Some(N_CT_3).opt_le(Some(N_CT_2)), Some(true));
1298 assert_eq!(Some(N_CT_3).opt_le(N_CT_3), Some(true));
1299
1300 assert_eq!(Some(P_CT_2).opt_lt(N_CT_3), Some(false));
1301 assert_eq!(Some(N_CT_3).opt_lt(Some(P_CT_2)), Some(true));
1302
1303 assert!(CT_3 > CT_2);
1304 assert!(Some(CT_3) > Some(CT_2));
1305 assert!(CT_2 > ClockTime::ZERO);
1306 assert!(Some(CT_2) > Some(ClockTime::ZERO));
1307 assert!(CT_3 > ClockTime::ZERO);
1308 assert!(Some(CT_3) > Some(ClockTime::ZERO));
1309
1310 assert!(!(ClockTime::NONE > None));
1311 assert!(!(Some(ClockTime::ZERO) < ClockTime::NONE));
1314 assert_eq!(Some(CT_3).opt_gt(Some(CT_2)), Some(true));
1315 assert_eq!(Some(CT_3).opt_ge(Some(CT_2)), Some(true));
1316 assert_eq!(Some(CT_3).opt_ge(CT_3), Some(true));
1317
1318 assert_eq!(Some(P_CT_3).opt_gt(Some(P_CT_2)), Some(true));
1319 assert_eq!(Some(P_CT_3).opt_ge(Some(P_CT_2)), Some(true));
1320 assert_eq!(Some(P_CT_3).opt_ge(P_CT_3), Some(true));
1321
1322 assert_eq!(Some(P_CT_0).opt_gt(P_CT_NONE), None);
1323 assert_eq!(P_CT_NONE.opt_gt(P_CT_0), None);
1324
1325 assert_eq!(Some(N_CT_3).opt_gt(Some(N_CT_2)), Some(false));
1326 assert_eq!(Some(N_CT_3).opt_ge(Some(N_CT_2)), Some(false));
1327 assert_eq!(Some(N_CT_3).opt_ge(N_CT_3), Some(true));
1328
1329 assert_eq!(Some(P_CT_2).opt_gt(N_CT_3), Some(true));
1330 assert_eq!(Some(N_CT_3).opt_gt(Some(P_CT_2)), Some(false));
1331
1332 assert!(!(ClockTime::NONE < None));
1333 assert!(!(ClockTime::NONE > None));
1334
1335 assert_eq!(Some(ClockTime::ZERO).opt_gt(ClockTime::NONE), None);
1339 assert_eq!(ClockTime::ZERO.opt_gt(ClockTime::NONE), None);
1340 assert_eq!(ClockTime::ZERO.opt_ge(ClockTime::NONE), None);
1341 assert_eq!(ClockTime::NONE.opt_gt(Some(ClockTime::ZERO)), None);
1342 assert_eq!(ClockTime::NONE.opt_gt(ClockTime::ZERO), None);
1343 assert_eq!(ClockTime::NONE.opt_ge(ClockTime::ZERO), None);
1344
1345 assert!(!(Some(ClockTime::ZERO) < ClockTime::NONE));
1346 assert_eq!(Some(ClockTime::ZERO).opt_lt(ClockTime::NONE), None);
1347 assert_eq!(Some(ClockTime::ZERO).opt_le(ClockTime::NONE), None);
1348
1349 assert_eq!(CT_3.opt_min(CT_2), Some(CT_2));
1350 assert_eq!(CT_3.opt_min(Some(CT_2)), Some(CT_2));
1351 assert_eq!(Some(CT_3).opt_min(Some(CT_2)), Some(CT_2));
1352 assert_eq!(ClockTime::NONE.opt_min(Some(CT_2)), None);
1353 assert_eq!(Some(CT_3).opt_min(ClockTime::NONE), None);
1354
1355 assert_eq!(P_CT_3.opt_min(P_CT_2), Some(P_CT_2));
1356 assert_eq!(P_CT_2.opt_min(P_CT_3), Some(P_CT_2));
1357 assert_eq!(N_CT_3.opt_min(N_CT_2), Some(N_CT_3));
1358 assert_eq!(N_CT_2.opt_min(N_CT_3), Some(N_CT_3));
1359 assert_eq!(P_CT_2.opt_min(N_CT_3), Some(N_CT_3));
1360
1361 assert_eq!(CT_3.opt_max(CT_2), Some(CT_3));
1362 assert_eq!(CT_3.opt_max(Some(CT_2)), Some(CT_3));
1363 assert_eq!(Some(CT_3).opt_max(Some(CT_2)), Some(CT_3));
1364 assert_eq!(ClockTime::NONE.opt_max(Some(CT_2)), None);
1365 assert_eq!(Some(CT_3).opt_max(ClockTime::NONE), None);
1366
1367 assert_eq!(P_CT_3.opt_max(P_CT_2), Some(P_CT_3));
1368 assert_eq!(P_CT_2.opt_max(P_CT_3), Some(P_CT_3));
1369 assert_eq!(N_CT_3.opt_max(N_CT_2), Some(N_CT_2));
1370 assert_eq!(N_CT_2.opt_max(N_CT_3), Some(N_CT_2));
1371 assert_eq!(P_CT_2.opt_max(N_CT_3), Some(P_CT_2));
1372 }
1373
1374 #[test]
1375 fn display() {
1376 let none = Option::<ClockTime>::None;
1377 let some = Some(45_834_908_569_837 * ClockTime::NSECOND);
1378 let lots = ClockTime::from_nseconds(u64::MAX - 1);
1379
1380 assert_eq!(format!("{:.0}", DisplayableOptClockTime(none)), "--:--:--");
1383 assert_eq!(
1384 format!("{:.3}", DisplayableOptClockTime(none)),
1385 "--:--:--.---"
1386 );
1387 assert_eq!(
1388 format!("{}", DisplayableOptClockTime(none)),
1389 "--:--:--.---------"
1390 );
1391
1392 assert_eq!(format!("{:.0}", DisplayableOptClockTime(some)), "12:43:54");
1393 assert_eq!(
1394 format!("{:.3}", DisplayableOptClockTime(some)),
1395 "12:43:54.908"
1396 );
1397 assert_eq!(
1398 format!("{}", DisplayableOptClockTime(some)),
1399 "12:43:54.908569837"
1400 );
1401
1402 assert_eq!(format!("{lots:.0}"), "5124095:34:33");
1403 assert_eq!(format!("{lots:.3}"), "5124095:34:33.709");
1404 assert_eq!(format!("{lots}"), "5124095:34:33.709551614");
1405
1406 assert_eq!(
1408 format!("{:.10}", DisplayableOptClockTime(none)),
1409 "--:--:--.---------"
1410 );
1411 assert_eq!(
1412 format!("{:.10}", DisplayableOptClockTime(some)),
1413 "12:43:54.908569837"
1414 );
1415 assert_eq!(format!("{lots:.10}"), "5124095:34:33.709551614");
1416
1417 assert_eq!(format!("{:4.0}", DisplayableOptClockTime(none)), "--:--:--");
1420 assert_eq!(
1421 format!("{:4.3}", DisplayableOptClockTime(none)),
1422 "--:--:--.---"
1423 );
1424 assert_eq!(
1425 format!("{:4}", DisplayableOptClockTime(none)),
1426 "--:--:--.---------"
1427 );
1428
1429 assert_eq!(format!("{:4.0}", DisplayableOptClockTime(some)), "12:43:54");
1430 assert_eq!(
1431 format!("{:4.3}", DisplayableOptClockTime(some)),
1432 "12:43:54.908"
1433 );
1434 assert_eq!(
1435 format!("{:4}", DisplayableOptClockTime(some)),
1436 "12:43:54.908569837"
1437 );
1438
1439 assert_eq!(format!("{lots:4.0}"), "5124095:34:33");
1440 assert_eq!(format!("{lots:4.3}"), "5124095:34:33.709");
1441 assert_eq!(format!("{lots:4}"), "5124095:34:33.709551614");
1442
1443 assert_eq!(
1446 format!("{:>9.0}", DisplayableOptClockTime(none)),
1447 " --:--:--"
1448 );
1449 assert_eq!(
1450 format!("{:<9.0}", DisplayableOptClockTime(none)),
1451 "--:--:-- "
1452 );
1453 assert_eq!(
1454 format!("{:^10.0}", DisplayableOptClockTime(none)),
1455 " --:--:-- "
1456 );
1457 assert_eq!(
1458 format!("{:>13.3}", DisplayableOptClockTime(none)),
1459 " --:--:--.---"
1460 );
1461 assert_eq!(
1462 format!("{:<13.3}", DisplayableOptClockTime(none)),
1463 "--:--:--.--- "
1464 );
1465 assert_eq!(
1466 format!("{:^14.3}", DisplayableOptClockTime(none)),
1467 " --:--:--.--- "
1468 );
1469 assert_eq!(
1470 format!("{:>19}", DisplayableOptClockTime(none)),
1471 " --:--:--.---------"
1472 );
1473 assert_eq!(
1474 format!("{:<19}", DisplayableOptClockTime(none)),
1475 "--:--:--.--------- "
1476 );
1477 assert_eq!(
1478 format!("{:^20}", DisplayableOptClockTime(none)),
1479 " --:--:--.--------- "
1480 );
1481
1482 assert_eq!(
1483 format!("{:>9.0}", DisplayableOptClockTime(some)),
1484 " 12:43:54"
1485 );
1486 assert_eq!(
1487 format!("{:<9.0}", DisplayableOptClockTime(some)),
1488 "12:43:54 "
1489 );
1490 assert_eq!(
1491 format!("{:^10.0}", DisplayableOptClockTime(some)),
1492 " 12:43:54 "
1493 );
1494 assert_eq!(
1495 format!("{:>13.3}", DisplayableOptClockTime(some)),
1496 " 12:43:54.908"
1497 );
1498 assert_eq!(
1499 format!("{:<13.3}", DisplayableOptClockTime(some)),
1500 "12:43:54.908 "
1501 );
1502 assert_eq!(
1503 format!("{:^14.3}", DisplayableOptClockTime(some)),
1504 " 12:43:54.908 "
1505 );
1506 assert_eq!(
1507 format!("{:>19}", DisplayableOptClockTime(some)),
1508 " 12:43:54.908569837"
1509 );
1510 assert_eq!(
1511 format!("{:<19}", DisplayableOptClockTime(some)),
1512 "12:43:54.908569837 "
1513 );
1514 assert_eq!(
1515 format!("{:^20}", DisplayableOptClockTime(some)),
1516 " 12:43:54.908569837 "
1517 );
1518
1519 assert_eq!(format!("{lots:>14.0}"), " 5124095:34:33");
1520 assert_eq!(format!("{lots:<14.0}"), "5124095:34:33 ");
1521 assert_eq!(format!("{lots:^15.0}"), " 5124095:34:33 ");
1522 assert_eq!(format!("{lots:>18.3}"), " 5124095:34:33.709");
1523 assert_eq!(format!("{lots:<18.3}"), "5124095:34:33.709 ");
1524 assert_eq!(format!("{lots:^19.3}"), " 5124095:34:33.709 ");
1525 assert_eq!(format!("{lots:>24}"), " 5124095:34:33.709551614");
1526 assert_eq!(format!("{lots:<24}"), "5124095:34:33.709551614 ");
1527 assert_eq!(format!("{lots:^25}"), " 5124095:34:33.709551614 ");
1528
1529 assert_eq!(
1532 format!("{:+11.0}", DisplayableOptClockTime(none)),
1533 " --:--:--"
1534 );
1535 assert_eq!(
1536 format!("{:011.0}", DisplayableOptClockTime(none)),
1537 "-----:--:--"
1538 );
1539 assert_eq!(
1540 format!("{:+011.0}", DisplayableOptClockTime(none)),
1541 "-----:--:--"
1542 );
1543 assert_eq!(
1544 format!("{:+15.3}", DisplayableOptClockTime(none)),
1545 " --:--:--.---"
1546 );
1547 assert_eq!(
1548 format!("{:015.3}", DisplayableOptClockTime(none)),
1549 "-----:--:--.---"
1550 );
1551 assert_eq!(
1552 format!("{:+015.3}", DisplayableOptClockTime(none)),
1553 "-----:--:--.---"
1554 );
1555 assert_eq!(
1556 format!("{:+21}", DisplayableOptClockTime(none)),
1557 " --:--:--.---------"
1558 );
1559 assert_eq!(
1560 format!("{:021}", DisplayableOptClockTime(none)),
1561 "-----:--:--.---------"
1562 );
1563 assert_eq!(
1564 format!("{:+021}", DisplayableOptClockTime(none)),
1565 "-----:--:--.---------"
1566 );
1567
1568 assert_eq!(
1569 format!("{:+11.0}", DisplayableOptClockTime(some)),
1570 " +12:43:54"
1571 );
1572 assert_eq!(
1573 format!("{:011.0}", DisplayableOptClockTime(some)),
1574 "00012:43:54"
1575 );
1576 assert_eq!(
1577 format!("{:+011.0}", DisplayableOptClockTime(some)),
1578 "+0012:43:54"
1579 );
1580 assert_eq!(
1581 format!("{:+15.3}", DisplayableOptClockTime(some)),
1582 " +12:43:54.908"
1583 );
1584 assert_eq!(
1585 format!("{:015.3}", DisplayableOptClockTime(some)),
1586 "00012:43:54.908"
1587 );
1588 assert_eq!(
1589 format!("{:+015.3}", DisplayableOptClockTime(some)),
1590 "+0012:43:54.908"
1591 );
1592 assert_eq!(
1593 format!("{:+21}", DisplayableOptClockTime(some)),
1594 " +12:43:54.908569837"
1595 );
1596 assert_eq!(
1597 format!("{:021}", DisplayableOptClockTime(some)),
1598 "00012:43:54.908569837"
1599 );
1600 assert_eq!(
1601 format!("{:+021}", DisplayableOptClockTime(some)),
1602 "+0012:43:54.908569837"
1603 );
1604
1605 assert_eq!(format!("{lots:+16.0}"), " +5124095:34:33");
1606 assert_eq!(format!("{lots:016.0}"), "0005124095:34:33");
1607 assert_eq!(format!("{lots:+016.0}"), "+005124095:34:33");
1608 assert_eq!(format!("{lots:+20.3}"), " +5124095:34:33.709");
1609 assert_eq!(format!("{lots:020.3}"), "0005124095:34:33.709");
1610 assert_eq!(format!("{lots:+020.3}"), "+005124095:34:33.709");
1611 assert_eq!(format!("{lots:+26}"), " +5124095:34:33.709551614");
1612 assert_eq!(format!("{lots:026}"), "0005124095:34:33.709551614");
1613 assert_eq!(format!("{lots:+026}"), "+005124095:34:33.709551614");
1614 }
1615
1616 #[test]
1617 fn iter_sum() {
1618 let s: ClockTime = vec![ClockTime::from_seconds(1), ClockTime::from_seconds(2)]
1619 .into_iter()
1620 .sum();
1621 assert_eq!(s, ClockTime::from_seconds(3));
1622 }
1623
1624 #[test]
1625 #[should_panic]
1626 fn attempt_to_build_from_clock_time_none() {
1627 let _ = ClockTime::from_nseconds(ffi::GST_CLOCK_TIME_NONE);
1628 }
1629
1630 #[test]
1631 #[should_panic]
1632 fn attempt_to_build_from_u64max() {
1633 let _ = ClockTime::from_nseconds(u64::MAX);
1634 }
1635
1636 #[test]
1637 fn try_into_signed() {
1638 let time = crate::Signed::Positive(ClockTime::from_nseconds(0));
1639 assert_eq!(i64::try_from(time), Ok(0));
1640
1641 let time = crate::Signed::Positive(ClockTime::from_nseconds(123));
1642 assert_eq!(i64::try_from(time), Ok(123));
1643
1644 let time = crate::Signed::Positive(ClockTime::from_nseconds(u64::MAX - 1));
1645 assert!(i64::try_from(time).is_err());
1646
1647 let time = crate::Signed::Positive(ClockTime::from_nseconds(u64::MAX >> 1));
1648 assert_eq!(i64::MAX as i128, (u64::MAX >> 1) as i128);
1649 assert_eq!(i64::try_from(time), Ok(i64::MAX));
1650
1651 let time = crate::Signed::Negative(ClockTime::from_nseconds(0));
1652 assert_eq!(i64::try_from(time), Ok(0));
1653
1654 let time = crate::Signed::Negative(ClockTime::from_nseconds(123));
1655 assert_eq!(i64::try_from(time), Ok(-123));
1656
1657 let time = crate::Signed::Negative(ClockTime::from_nseconds(u64::MAX - 1));
1658 assert!(i64::try_from(time).is_err());
1659
1660 let time = crate::Signed::Negative(ClockTime::from_nseconds(u64::MAX >> 1));
1661 assert_eq!(i64::MIN as i128 + 1, -((u64::MAX >> 1) as i128));
1662 assert_eq!(i64::try_from(time), Ok(i64::MIN + 1));
1663
1664 let time = crate::Signed::Negative(ClockTime::from_nseconds((u64::MAX >> 1) + 1));
1665 assert_eq!(i64::MIN as i128, -(((u64::MAX >> 1) + 1) as i128));
1666 assert_eq!(i64::try_from(time), Ok(i64::MIN));
1667 }
1668
1669 #[test]
1670 fn properties_macro_usage() {
1671 use super::ClockTime;
1672 use glib::{prelude::*, subclass::prelude::*};
1673 use std::cell::Cell;
1674
1675 #[derive(Default, glib::Properties)]
1676 #[properties(wrapper_type = TestObject)]
1677 pub struct TestObjectImp {
1678 #[property(get, set)]
1679 clock_time: Cell<ClockTime>,
1680 #[property(get, set)]
1681 optional_clock_time: Cell<Option<ClockTime>>,
1682 }
1683
1684 #[glib::object_subclass]
1685 impl ObjectSubclass for TestObjectImp {
1686 const NAME: &'static str = "GstTestObject";
1687 type Type = TestObject;
1688 }
1689
1690 impl ObjectImpl for TestObjectImp {
1691 fn properties() -> &'static [glib::ParamSpec] {
1692 Self::derived_properties()
1693 }
1694
1695 fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
1696 self.derived_set_property(id, value, pspec);
1697 }
1698
1699 fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value {
1700 self.derived_property(id, pspec)
1701 }
1702 }
1703
1704 glib::wrapper! {
1705 pub struct TestObject(ObjectSubclass<TestObjectImp>);
1706 }
1707
1708 let obj: TestObject = glib::Object::new();
1709
1710 assert_eq!(obj.clock_time(), ClockTime::default());
1711 obj.set_clock_time(ClockTime::MAX);
1712 assert_eq!(obj.clock_time(), ClockTime::MAX);
1713
1714 assert_eq!(obj.optional_clock_time(), None);
1715 obj.set_optional_clock_time(ClockTime::MAX);
1716 assert_eq!(obj.optional_clock_time(), Some(ClockTime::MAX));
1717 }
1718
1719 #[test]
1720 fn seconds_float() {
1721 let res = ClockTime::ZERO;
1722 assert_eq!(res.seconds_f32(), 0.0);
1723 assert_eq!(res.seconds_f64(), 0.0);
1724
1725 let res = ClockTime::from_nseconds(2_700_000_000);
1726 assert_eq!(res.seconds_f32(), 2.7);
1727 assert_eq!(res.seconds_f64(), 2.7);
1728
1729 let res = ClockTime::MAX;
1730 assert_eq!(res.seconds_f32(), 18_446_744_073.709_553);
1731 assert_eq!(res.seconds_f64(), 18_446_744_073.709_553);
1732 }
1733
1734 #[test]
1735 fn seconds_float_signed() {
1736 let pos = Signed::Positive(ClockTime::ZERO);
1737 assert_eq!(pos.seconds_f32(), 0.0);
1738 assert_eq!(pos.seconds_f64(), 0.0);
1739 let neg = Signed::Negative(ClockTime::ZERO);
1740 assert_eq!(neg.seconds_f32(), 0.0);
1741 assert_eq!(neg.seconds_f64(), 0.0);
1742
1743 let pos = Signed::Positive(ClockTime::from_nseconds(2_700_000_000));
1744 assert_eq!(pos.seconds_f32(), 2.7);
1745 assert_eq!(pos.seconds_f64(), 2.7);
1746 let neg = Signed::Negative(ClockTime::from_nseconds(2_700_000_000));
1747 assert_eq!(neg.seconds_f32(), -2.7);
1748 assert_eq!(neg.seconds_f64(), -2.7);
1749
1750 let pos = Signed::Positive(ClockTime::MAX);
1751 assert_eq!(pos.seconds_f32(), 18_446_744_073.709_553);
1752 assert_eq!(pos.seconds_f64(), 18_446_744_073.709_553);
1753 let neg = Signed::Negative(ClockTime::MAX);
1754 assert_eq!(neg.seconds_f32(), -18_446_744_073.709_553);
1755 assert_eq!(neg.seconds_f64(), -18_446_744_073.709_553);
1756 }
1757
1758 #[test]
1759 fn try_from_seconds_f32() {
1760 let res = ClockTime::try_from_seconds_f32(0.0);
1761 assert_eq!(res, Ok(ClockTime::ZERO));
1762 let res = ClockTime::try_from_seconds_f32(1e-20);
1763 assert_eq!(res, Ok(ClockTime::ZERO));
1764 let res = ClockTime::try_from_seconds_f32(4.2e-7);
1765 assert_eq!(res, Ok(ClockTime::from_nseconds(420)));
1766 let res = ClockTime::try_from_seconds_f32(2.7);
1767 assert_eq!(res, Ok(ClockTime::from_nseconds(2_700_000_048)));
1768 let res = ClockTime::try_from_seconds_f32(f32::from_bits(1));
1770 assert_eq!(res, Ok(ClockTime::ZERO));
1771
1772 let res = ClockTime::try_from_seconds_f32(0.999e-9);
1774 assert_eq!(res, Ok(ClockTime::from_nseconds(1)));
1775
1776 let res = ClockTime::try_from_seconds_f32(-5.0);
1777 assert!(res.is_err());
1778 let res = ClockTime::try_from_seconds_f32(f32::NAN);
1779 assert!(res.is_err());
1780 let res = ClockTime::try_from_seconds_f32(2e19);
1781 assert!(res.is_err());
1782
1783 let val = f32::from_bits(0x3A80_0000);
1785 let res = ClockTime::try_from_seconds_f32(val);
1786 assert_eq!(res, Ok(ClockTime::from_nseconds(976_562)));
1787
1788 let val = f32::from_bits(0x3B40_0000);
1790 let res = ClockTime::try_from_seconds_f32(val);
1791 assert_eq!(res, Ok(ClockTime::from_nseconds(2_929_688)));
1792
1793 let val = f32::from_bits(0x3F802000);
1795 let res = ClockTime::try_from_seconds_f32(val);
1796 assert_eq!(res, Ok(ClockTime::from_nseconds(1_000_976_562)));
1797
1798 let val = f32::from_bits(0x3F806000);
1800 let res = ClockTime::try_from_seconds_f32(val);
1801 assert_eq!(res, Ok(ClockTime::from_nseconds(1_002_929_688)));
1802 }
1803
1804 #[test]
1805 fn try_from_seconds_f64() {
1806 let res = ClockTime::try_from_seconds_f64(0.0);
1807 assert_eq!(res, Ok(ClockTime::ZERO));
1808 let res = ClockTime::try_from_seconds_f64(1e-20);
1809 assert_eq!(res, Ok(ClockTime::ZERO));
1810 let res = ClockTime::try_from_seconds_f64(4.2e-7);
1811 assert_eq!(res, Ok(ClockTime::from_nseconds(420)));
1812 let res = ClockTime::try_from_seconds_f64(2.7);
1813 assert_eq!(res, Ok(ClockTime::from_nseconds(2_700_000_000)));
1814 let res = ClockTime::try_from_seconds_f64(f64::from_bits(1));
1816 assert_eq!(res, Ok(ClockTime::ZERO));
1817
1818 let res = ClockTime::try_from_seconds_f64(0.999e-9);
1820 assert_eq!(res, Ok(ClockTime::from_nseconds(1)));
1821 let res = ClockTime::try_from_seconds_f64(0.999_999_999_499);
1822 assert_eq!(res, Ok(ClockTime::from_nseconds(999_999_999)));
1823 let res = ClockTime::try_from_seconds_f64(0.999_999_999_501);
1824 assert_eq!(res, Ok(ClockTime::from_seconds(1)));
1825 let res = ClockTime::try_from_seconds_f64(42.999_999_999_499);
1826 assert_eq!(res, Ok(ClockTime::from_nseconds(42_999_999_999)));
1827 let res = ClockTime::try_from_seconds_f64(42.999_999_999_501);
1828 assert_eq!(res, Ok(ClockTime::from_seconds(43)));
1829
1830 let res = ClockTime::try_from_seconds_f64(-5.0);
1831 assert!(res.is_err());
1832 let res = ClockTime::try_from_seconds_f64(f64::NAN);
1833 assert!(res.is_err());
1834 let res = ClockTime::try_from_seconds_f64(2e19);
1835 assert!(res.is_err());
1836
1837 let val = f64::from_bits(0x3F50_0000_0000_0000);
1839 let res = ClockTime::try_from_seconds_f64(val);
1840 assert_eq!(res, Ok(ClockTime::from_nseconds(976_562)));
1841
1842 let val = f64::from_bits(0x3F68_0000_0000_0000);
1844 let res = ClockTime::try_from_seconds_f64(val);
1845 assert_eq!(res, Ok(ClockTime::from_nseconds(2_929_688)));
1846
1847 let val = f64::from_bits(0x3FF0_0400_0000_0000);
1849 let res = ClockTime::try_from_seconds_f64(val);
1850 assert_eq!(res, Ok(ClockTime::from_nseconds(1_000_976_562)));
1851
1852 let val = f64::from_bits(0x3FF0_0C00_0000_0000);
1854 let res = ClockTime::try_from_seconds_f64(val);
1855 assert_eq!(res, Ok(ClockTime::from_nseconds(1_002_929_688)));
1856 }
1857
1858 #[test]
1859 fn try_from_seconds_f32_signed() {
1860 let pos = Signed::<ClockTime>::from_seconds_f32(5.0);
1861 assert!(pos.is_positive());
1862
1863 let neg = Signed::<ClockTime>::from_seconds_f32(-5.0);
1864 assert!(neg.is_negative());
1865 }
1866
1867 #[test]
1868 fn try_from_seconds_f64_signed() {
1869 let pos = Signed::<ClockTime>::from_seconds_f64(5.0);
1870 assert!(pos.is_positive());
1871
1872 let neg = Signed::<ClockTime>::from_seconds_f64(-5.0);
1873 assert!(neg.is_negative());
1874 }
1875
1876 #[test]
1877 fn absdiff() {
1878 let t1 = ClockTime::from_seconds(10);
1879 let t2 = ClockTime::from_seconds(4);
1880
1881 let d = ClockTime::from_seconds(6);
1882
1883 assert_eq!(t1.absdiff(t2), d);
1884 assert_eq!(t2.absdiff(t1), d);
1885 }
1886}