motion_core/time/
offset.rs1use std::ops::{Add, AddAssign, Neg, Sub, SubAssign};
4
5use super::{Duration, TICKS_PER_SECOND, try_rounded_ticks};
6
7#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
13pub struct TimeOffset(i64);
14
15impl TimeOffset {
16 pub const ZERO: Self = Self(0);
18
19 pub const fn from_ticks(ticks: i64) -> Self {
21 Self(ticks)
22 }
23
24 pub fn from_seconds(seconds: f64) -> Self {
30 Self::try_from_seconds(seconds).unwrap_or_else(|error| panic!("{}", error.message))
31 }
32
33 pub fn try_from_seconds(seconds: f64) -> Result<Self, crate::ValidationError> {
35 try_rounded_ticks(seconds * TICKS_PER_SECOND as f64).map(Self)
36 }
37
38 pub const fn ticks(self) -> i64 {
40 self.0
41 }
42
43 pub fn as_seconds(self) -> f64 {
45 self.0 as f64 / TICKS_PER_SECOND as f64
46 }
47
48 pub const fn is_negative(self) -> bool {
50 self.0 < 0
51 }
52
53 pub const fn magnitude(self) -> Duration {
55 Duration::from_ticks(self.0.unsigned_abs())
56 }
57
58 pub const fn to_duration(self) -> Option<Duration> {
60 if self.0 < 0 {
61 None
62 } else {
63 Some(Duration::from_ticks(self.0 as u64))
64 }
65 }
66}
67
68impl Add for TimeOffset {
69 type Output = Self;
70
71 fn add(self, other: Self) -> Self {
72 Self(
73 self.0
74 .checked_add(other.0)
75 .expect("offset addition overflow"),
76 )
77 }
78}
79
80impl Sub for TimeOffset {
81 type Output = Self;
82
83 fn sub(self, other: Self) -> Self {
84 Self(
85 self.0
86 .checked_sub(other.0)
87 .expect("offset subtraction overflow"),
88 )
89 }
90}
91
92impl AddAssign for TimeOffset {
93 fn add_assign(&mut self, other: Self) {
94 *self = *self + other;
95 }
96}
97
98impl SubAssign for TimeOffset {
99 fn sub_assign(&mut self, other: Self) {
100 *self = *self - other;
101 }
102}
103
104impl Neg for TimeOffset {
105 type Output = Self;
106
107 fn neg(self) -> Self {
108 Self(self.0.checked_neg().expect("offset negation overflow"))
109 }
110}