1use num_traits::{Float, FloatConst};
4use std::fmt::{Debug, Formatter, Result};
5use std::ops::{Add, Div, Neg, Sub};
6use std::time::Duration;
7
8pub struct Velocity<T> {
11 delta: T,
12 time: Duration,
13}
14
15impl<T> Velocity<T> {
16 pub fn new(delta: T, time: Duration) -> Velocity<T> {
18 Velocity { delta, time }
19 }
20
21 pub fn into_per_second<X, O>(self) -> O
24 where
25 X: From<f32>,
26 T: Div<X, Output = O>,
27 {
28 self.delta / X::from(self.time.as_secs_f32())
29 }
30}
31
32#[derive(Copy, Clone, Default, Eq, PartialEq)]
34pub struct Angle<T> {
35 radians: T,
36}
37
38impl<T> Angle<T>
39where
40 T: Float,
41{
42 pub fn with_radians(radians: T) -> Angle<T> {
44 Angle { radians }
45 }
46
47 pub fn to_radians(&self) -> T {
49 self.radians
50 }
51}
52
53impl<T> Angle<T>
54where
55 T: Float + FloatConst,
56{
57 pub fn with_degrees(degrees: T) -> Angle<T> {
59 Angle {
60 radians: degrees / T::from(180.0).unwrap() * T::PI(),
61 }
62 }
63
64 pub fn to_degrees(&self) -> T {
66 self.radians / T::PI() * T::from(180.0).unwrap()
67 }
68}
69
70impl<T> Add for &Angle<T>
71where
72 T: Float + FloatConst,
73{
74 type Output = Angle<T>;
75
76 fn add(self, rhs: &Angle<T>) -> Self::Output {
77 Angle {
78 radians: self.radians + rhs.radians,
79 }
80 }
81}
82
83impl<T> Sub for &Angle<T>
84where
85 T: Float + FloatConst,
86{
87 type Output = Angle<T>;
88
89 fn sub(self, rhs: &Angle<T>) -> Self::Output {
90 Angle {
91 radians: self.radians - rhs.radians,
92 }
93 }
94}
95
96impl<T> Neg for Angle<T>
97where
98 T: Neg,
99{
100 type Output = Angle<T::Output>;
101
102 fn neg(self) -> Self::Output {
103 Angle {
104 radians: self.radians.neg(),
105 }
106 }
107}
108
109impl<T> Debug for Angle<T>
110where
111 T: Float + FloatConst + Debug,
112{
113 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
114 f.write_fmt(format_args!("{:?}ยบ", self.to_degrees()))
115 }
116}