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