#![crate_name = "syunit"]
#![doc = include_str!("../README.md")]
#![no_std]
#![deny(missing_docs)]
use core::ops::{Add, AddAssign, Div, Sub, SubAssign};
use core::time::Duration;
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
mod funcs;
pub use funcs::*;
mod macros;
mod specials;
pub use specials::*;
use crate as syunit;
pub trait Unit : Into<f32> {
fn new(v : f32) -> Self
where
Self : Sized;
}
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Time(pub f32);
basic_unit!(Time);
additive_unit!(Time);
impl Into<Duration> for Time {
#[inline(always)]
fn into(self) -> Duration {
Duration::from_secs_f32(self.0)
}
}
impl Div<Time> for f32 {
type Output = Velocity;
#[inline(always)]
fn div(self, rhs: Time) -> Self::Output {
Velocity(self / rhs.0)
}
}
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Factor(f32);
impl Factor {
pub const MAX : Self = Self(1.0);
pub const HALF : Self = Self(0.5);
pub const MIN : Self = Self(0.0);
pub fn new(val : f32) -> Self {
if (val >= 0.0) & (val <= 1.0) {
Self(val)
} else {
panic!("The given value is out of bounds for a Factor! ({})", val);
}
}
pub fn try_new(val : f32) -> Option<Self> {
if (val >= 0.0) & (val <= 1.0) {
Some(Self(val))
} else {
None
}
}
pub const unsafe fn new_unchecked(val : f32) -> Self {
Self(val)
}
pub fn get_duty(self) -> u16 {
((u16::MAX as f32) * self.0) as u16
}
pub fn get_duty_for(self, max_duty : u16) -> u16 {
((max_duty as f32) * self.0) as u16
}
}
impl core::ops::Mul<Factor> for Factor {
type Output = Factor;
fn mul(self, rhs: Factor) -> Self::Output {
Self::new(self.0 * rhs.0)
}
}
impl core::ops::Mul<Factor> for Velocity {
type Output = Velocity;
fn mul(self, rhs: Factor) -> Self::Output {
Self::new(self.0 * rhs.0)
}
}
impl core::fmt::Display for Factor {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.fmt(f)
}
}
impl core::fmt::Debug for Factor {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_fmt(format_args!("Factor({})", self.0))
}
}
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Gamma(pub f32);
basic_unit!(Gamma);
impl Gamma {
pub fn force_to_phi(self) -> Phi {
Phi(self.0)
}
}
impl Sub<Gamma> for Gamma {
type Output = Delta;
#[inline(always)]
fn sub(self, rhs: Gamma) -> Self::Output {
Delta(self.0 - rhs.0)
}
}
impl Add<Delta> for Gamma {
type Output = Gamma;
#[inline(always)]
fn add(self, rhs: Delta) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl Add<Gamma> for Delta {
type Output = Delta;
#[inline(always)]
fn add(self, rhs: Gamma) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl AddAssign<Delta> for Gamma {
fn add_assign(&mut self, rhs: Delta) {
self.0 += rhs.0;
}
}
impl Sub<Delta> for Gamma {
type Output = Gamma;
#[inline]
fn sub(self, rhs: Delta) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl SubAssign for Gamma {
fn sub_assign(&mut self, rhs: Self) {
self.0 -= rhs.0;
}
}
#[inline]
pub fn force_phis_from_gammas<const N : usize>(gammas : [Gamma; N]) -> [Phi; N] {
let mut phis = [Phi::ZERO; N];
for i in 0 .. N {
phis[i] = gammas[i].force_to_phi();
}
phis
}
#[inline]
pub fn force_gammas_from_phis<const N : usize>(phis : [Phi; N]) -> [Gamma; N] {
let mut gammas = [Gamma::ZERO; N];
for i in 0 .. N {
gammas[i] = phis[i].force_to_gamma();
}
gammas
}
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Phi(pub f32);
basic_unit!(Phi);
impl Phi {
pub fn force_to_gamma(self) -> Gamma {
Gamma(self.0)
}
}
impl Sub<Phi> for Phi {
type Output = Delta;
fn sub(self, rhs: Phi) -> Self::Output {
Delta(self.0 - rhs.0)
}
}
impl Add<Delta> for Phi {
type Output = Phi;
#[inline(always)]
fn add(self, rhs : Delta) -> Self::Output {
Phi(self.0 + rhs.0)
}
}
impl Add<Phi> for Delta {
type Output = Phi;
#[inline(always)]
fn add(self, rhs: Phi) -> Self::Output {
Phi(self.0 + rhs.0)
}
}
impl AddAssign<Delta> for Phi {
fn add_assign(&mut self, rhs: Delta) {
self.0 += rhs.0;
}
}
impl Sub<Delta> for Phi {
type Output = Phi;
#[inline(always)]
fn sub(self, rhs: Delta) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl SubAssign<Delta> for Phi {
fn sub_assign(&mut self, rhs: Delta) {
self.0 += rhs.0;
}
}
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Delta(pub f32);
basic_unit!(Delta);
additive_unit!(Delta);
impl Delta {
#[inline(always)]
pub fn diff(start : Gamma, end : Gamma) -> Self {
end - start
}
}
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Velocity(pub f32);
basic_unit!(Velocity);
additive_unit!(Velocity);
derive_units!(Delta, Velocity, Time);
impl Div<Velocity> for f32 {
type Output = Time;
#[inline(always)]
fn div(self, rhs: Velocity) -> Self::Output {
Time(self / rhs.0)
}
}
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Frequency(pub f32);
basic_unit!(Frequency);
additive_unit!(Frequency);
impl Div<Frequency> for f32 {
type Output = Time;
#[inline(always)]
fn div(self, rhs: Frequency) -> Self::Output {
Time(self / rhs.0)
}
}
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Acceleration(pub f32);
basic_unit!(Acceleration);
additive_unit!(Acceleration);
derive_units!(Velocity, Acceleration, Time);
derive_units!(Force, Acceleration, Inertia);
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Jolt(pub f32);
basic_unit!(Jolt);
additive_unit!(Jolt);
derive_units!(Acceleration, Jolt, Time);
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Inertia(pub f32);
basic_unit!(Inertia);
additive_unit!(Inertia);
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Force(pub f32);
basic_unit!(Force);
additive_unit!(Force);