1
2use std::time::{Instant, Duration};
3use std::default::Default;
4use std::fmt;
5use std::ops::{Add, Sub};
6use rust_decimal::Decimal;
7
8#[derive(Default, Clone, Copy)]
9pub struct TimeSpan {
10 nanos: u128,
11}
12
13impl From<Duration> for TimeSpan {
14 fn from(d:Duration) -> Self {
15 Self{
16 nanos: d.as_nanos(),
17 }
18 }
19}
20
21impl Into<Duration> for TimeSpan{
22 fn into(self) -> Duration{
23 Duration::from_nanos(self.nanos as u64)
24 }
25}
26
27impl Add<TimeSpan> for TimeSpan{
28 type Output = TimeSpan;
29 fn add(self, t: TimeSpan) -> TimeSpan {
30 TimeSpan{
31 nanos: self.nanos + t.nanos
32 }
33 }
34}
35
36impl Add<Duration> for TimeSpan{
37 type Output = TimeSpan;
38 fn add(self, d: Duration) -> TimeSpan {
39 TimeSpan{
40 nanos: self.nanos + d.as_nanos()
41 }
42 }
43}
44
45
46impl Sub<TimeSpan> for TimeSpan{
47 type Output = TimeSpan;
48 fn sub(self, t: TimeSpan) -> TimeSpan {
49 TimeSpan{
50 nanos: self.nanos - t.nanos
51 }
52 }
53}
54
55impl Sub<Duration> for TimeSpan{
56 type Output = TimeSpan;
57 fn sub(self, d: Duration) -> TimeSpan {
58 TimeSpan{
59 nanos: self.nanos - d.as_nanos()
60 }
61 }
62}
63
64
65
66
67impl TimeSpan {
68 const NANOS_PER_MILLI: u128 = 1_000_000;
70 const NANOS_PER_SEC: u128 = 1_000_000_000;
71 const NANOS_PER_MINUTE: u128 = Self::NANOS_PER_SEC * 60;
72 const NANOS_PER_HOUR: u128 = Self::NANOS_PER_MINUTE * 60;
73 const NANOS_PER_DAY: u128 = Self::NANOS_PER_HOUR * 24;
74
75
76
77 pub fn total_days(&self) -> Decimal{
78 Decimal::new(self.nanos as i64, 0) * (Decimal::new(1, 0) / Decimal::new(Self::NANOS_PER_DAY as i64, 0))
79 }
80
81 pub fn total_hours(&self) -> Decimal{
82 Decimal::new(self.nanos as i64, 0) * (Decimal::new(1, 0) / Decimal::new(Self::NANOS_PER_HOUR as i64, 0))
83 }
84
85 pub fn total_minutes(&self) -> Decimal{
86 Decimal::new(self.nanos as i64, 0) * (Decimal::new(1, 0) / Decimal::new(Self::NANOS_PER_MINUTE as i64, 0))
87 }
88
89 pub fn total_seconds(&self) -> Decimal{
90 Decimal::new(self.nanos as i64, 0) * (Decimal::new(1, 0) / Decimal::new(Self::NANOS_PER_SEC as i64, 0))
91 }
92
93 pub fn total_ms(&self) -> Decimal {
94 Decimal::new(self.nanos as i64, 0) * (Decimal::new(1, 0) / Decimal::new(Self::NANOS_PER_MILLI as i64, 0))
95 }
96 pub fn total_nano(&self) -> u128 {
97 self.nanos
98 }
99
100 pub fn days(&self) -> u32 {
101 (self.nanos / Self::NANOS_PER_DAY) as u32
102 }
103 pub fn hours(&self) -> u32 {
104 ((self.nanos / Self::NANOS_PER_HOUR) % 24) as u32
105 }
106 pub fn minutes(&self) -> u32 {
107 ((self.nanos / Self::NANOS_PER_MINUTE) % 60) as u32
108 }
109 pub fn seconds(&self) -> u32 {
110 ((self.nanos / Self::NANOS_PER_SEC) % 60) as u32
111 }
112
113 pub fn ms(&self) -> u32 {
114 ((self.nanos / Self::NANOS_PER_MILLI) % 1000) as u32
115 }
116
117 pub fn nanos(&self) -> u128 {
118 self.nanos
119 }
120
121}
122
123#[derive(Default, Clone, Copy)]
124pub struct Profiler {
125 start_time: Option<Instant>,
126 end_time: Option<Instant>,
127 elapsed_time: TimeSpan,
128}
129
130impl fmt::Display for Profiler {
131 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
132 let elapsed = self.elapsed();
133 return write!(f, "{}ms", elapsed.total_minutes());
134 }
135}
136
137impl Profiler {
138 pub fn new() -> Self {
139 Default::default()
140 }
141
142 pub fn start_new() -> Self{
143 let mut inst = Self::default();
144 inst.start();
145 inst
146 }
147
148 pub fn start(&mut self) {
149 if self.start_time.is_none(){
150 self.start_time = Some(Instant::now());
151 }
152 }
153
154 pub fn stop(&mut self) {
155 if self.end_time.is_none(){
156 self.end_time = Some(Instant::now());
157 }
158
159 if let (Some(start), Some(end)) = (self.start_time, self.end_time){
160 self.elapsed_time = (end - start).into();
161 }else{
162 self.elapsed_time = TimeSpan::default();
163 }
164 }
165
166 pub fn clear(&mut self) {
167 self.start_time = None;
168 self.end_time = None
169 }
170
171 pub fn since_started(&self) -> TimeSpan{
172 let current_inst = Instant::now();
173 if let Some(started) = self.start_time{
174 (current_inst - started).into()
175 }else{
176 Duration::from_secs(0).into()
177 }
178 }
179
180 pub fn elapsed(&self) -> TimeSpan {
181 self.elapsed_time
182 }
183
184}