// Copyright (c) 2026 The WebRTC project authors. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. use cxx::{type_id, ExternType}; #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] #[repr(transparent)] pub struct TimeDelta { pub(crate) microseconds: i64, } unsafe impl ExternType for TimeDelta { type Id = type_id!("webrtc::TimeDelta"); type Kind = cxx::kind::Trivial; } impl Default for TimeDelta { fn default() -> Self { Self::zero() } } impl TimeDelta { pub const fn ms(&self) -> i64 { self.microseconds / 1000 } pub const fn us(&self) -> i64 { self.microseconds } pub const fn from_millis(value: i64) -> Self { Self { microseconds: value * 1000 } } pub const fn from_micros(value: i64) -> Self { Self { microseconds: value } } pub const fn zero() -> Self { Self { microseconds: 0 } } pub const fn seconds_f64(&self) -> f64 { self.microseconds as f64 / 1_000_000.0 } } impl std::ops::Add for TimeDelta { type Output = Self; fn add(self, rhs: Self) -> Self { Self { microseconds: self.microseconds + rhs.microseconds } } } impl std::ops::Sub for TimeDelta { type Output = Self; fn sub(self, rhs: Self) -> Self { Self { microseconds: self.microseconds - rhs.microseconds } } } impl std::ops::Mul for TimeDelta { type Output = Self; fn mul(self, rhs: i64) -> Self { Self { microseconds: self.microseconds * rhs } } } impl std::ops::Mul for TimeDelta { type Output = Self; fn mul(self, rhs: usize) -> Self { Self { microseconds: self.microseconds * i64::try_from(rhs).expect("usize too large for i64"), } } } impl std::ops::Div for TimeDelta { type Output = i64; fn div(self, rhs: Self) -> i64 { assert!(rhs.microseconds != 0); self.microseconds / rhs.microseconds } } impl std::ops::Div for TimeDelta { type Output = Self; fn div(self, rhs: i64) -> Self { assert!(rhs != 0); Self { microseconds: self.microseconds / rhs } } } impl std::ops::Rem for TimeDelta { type Output = Self; fn rem(self, rhs: Self) -> Self { assert!(rhs.microseconds != 0); Self { microseconds: self.microseconds % rhs.microseconds } } } impl std::ops::Shr for TimeDelta { type Output = Self; fn shr(self, rhs: i32) -> Self { Self { microseconds: self.microseconds >> rhs } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_millis() { let td = TimeDelta::from_millis(42); assert_eq!(td.ms(), 42); assert_eq!(td.us(), 42000); } #[test] fn test_micros() { let td = TimeDelta::from_micros(42); assert_eq!(td.us(), 42); } #[test] fn test_zero() { let td = TimeDelta::zero(); assert_eq!(td.us(), 0); } #[test] fn test_add() { let td1 = TimeDelta::from_millis(10); let td2 = TimeDelta::from_millis(20); let td3 = td1 + td2; assert_eq!(td3.ms(), 30); } #[test] fn test_sub() { let td1 = TimeDelta::from_millis(30); let td2 = TimeDelta::from_millis(10); let td3 = td1 - td2; assert_eq!(td3.ms(), 20); } }