use core::ops::{Div, Mul, Sub};
use rinia::numeric::{
Floor, LossyCast, One, SaturatingAdd, SaturatingCast, SaturatingSub, SignedCast,
SignedEquivalent, Zero,
};
use crate::{FrameIndex, FrameRate, Time, common};
impl<T> FrameIndex<T> {
#[inline]
pub fn new(value: T) -> Self {
FrameIndex(value)
}
#[inline]
pub const fn index(&self) -> T
where
T: Copy,
{
self.0
}
#[inline]
pub fn into_index(self) -> T {
self.0
}
#[inline]
pub fn from_time<S>(time: Time<S>, rate: FrameRate<S>) -> Self
where
S: Copy + Mul<Output = S> + Floor + SaturatingCast<T>,
{
common::frame_from_time(time, rate)
}
#[inline]
pub fn to_time<S>(self, rate: FrameRate<S>) -> Time<S>
where
T: Copy + LossyCast<S>,
S: Copy + Div<Output = S>,
{
common::time_from_frame(self, rate)
}
#[inline]
pub fn offset_from(self, other: Self) -> <T as SignedEquivalent>::Signed
where
T: SignedEquivalent + SignedCast<<T as SignedEquivalent>::Signed>,
<T as SignedEquivalent>::Signed: Sub<Output = <T as SignedEquivalent>::Signed>,
{
self.0.signed_cast() - other.0.signed_cast()
}
#[inline]
pub fn next(&self) -> Self
where
T: One + SaturatingAdd<Output = T>,
Self: Copy + SaturatingAdd<T, Output = Self>,
{
self.saturating_add_t(T::ONE)
}
#[inline]
pub fn previous(&self) -> Self
where
T: One + SaturatingSub<Output = T>,
Self: Copy + SaturatingSub<T, Output = Self>,
{
self.saturating_sub_t(T::ONE)
}
}
impl<T> Default for FrameIndex<T>
where
Self: Zero,
{
fn default() -> Self {
Self::ZERO
}
}
impl<T> From<T> for FrameIndex<T> {
#[inline]
fn from(value: T) -> Self {
Self::new(value)
}
}
impl From<FrameIndex<u32>> for u32 {
#[inline]
fn from(frame: FrameIndex<u32>) -> Self {
frame.index()
}
}
impl From<FrameIndex<u64>> for u64 {
#[inline]
fn from(frame: FrameIndex<u64>) -> Self {
frame.index()
}
}
impl From<FrameIndex<usize>> for usize {
#[inline]
fn from(frame: FrameIndex<usize>) -> Self {
frame.index()
}
}
common::impl_approx_forwarding!(FrameIndex<T>, 0);
common::impl_bytemuck_basic!(
[T],
FrameIndex<T>,
item: T,
);