Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_data/src/time.rs

2.9 KiB, 8 runs

created by r1870400018:277, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use oxedyne_fe2o3_core::{
2 prelude::*,
3 byte::{
4 FromBytes,
5 ToBytes,
6 },
7 mem::Extract,
8};
9use oxedyne_fe2o3_jdat::{
10 prelude::*,
11 try_extract_tup2dat,
12 tup2dat,
13};
14
15use std::{
16 fmt::Debug,
17 time::{
18 Duration,
19 SystemTime,
20 UNIX_EPOCH,
21 },
22};
23
24// Duration since the start of the unix epoch.
25new_type!(Timestamp, Duration, Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd);
26
27impl ToBytes for Timestamp {
28 fn to_bytes(&self, mut buf: Vec<u8>) -> Outcome<Vec<u8>> {
29 buf.extend_from_slice(&self.secs().to_be_bytes());
30 buf.extend_from_slice(&self.nanos().to_be_bytes());
31 Ok(buf)
32 }
33}
34
35impl FromBytes for Timestamp {
36 fn from_bytes(buf: &[u8]) -> Outcome<(Self, usize)> {
37 let secs = u64::from_be_bytes(res!(<[u8; 8]>::try_from(&buf[..8]), Decode, Bytes));
38 let nanos = u32::from_be_bytes(res!(<[u8; 4]>::try_from(&buf[8..12]), Decode, Bytes));
39 Ok((
40 Self::new(secs, nanos),
41 Self::BYTE_LEN,
42 ))
43 }
44}
45
46// ToDat for Timestamp automatically implemented by Deref.
47
48impl FromDat for Timestamp {
49 fn from_dat(dat: Dat) -> Outcome<Self> {
50 Ok(Self(res!(Duration::from_dat(dat))))
51 }
52}
53
54impl Timestamp {
55
56 pub const BYTE_LEN: usize = 12;
57
58 pub fn now() -> Outcome<Self> {
59 match SystemTime::now().duration_since(UNIX_EPOCH) {
60 Ok(n) => Ok(Self(n)),
61 Err(_) => Err(err!(
62 "The current SystemTime {:?} is before the Unix epoch {:?}, \
63 there is a problem with the system clock! Try resetting it.",
64 SystemTime::now(), UNIX_EPOCH;
65 System)),
66 }
67 }
68
69 pub fn new(secs: u64, nanos: u32) -> Self {
70 Self(Duration::new(secs, nanos))
71 }
72
73 pub fn secs(&self) -> u64 {
74 self.0.as_secs()
75 }
76
77 pub fn nanos(&self) -> u32 {
78 self.0.subsec_nanos()
79 }
80
81}
82
83#[derive(Clone, Debug, Default)]
84pub struct Timestamped<
85 D: Clone
86 + Debug
87 + Default
88 + ToDat
89 + FromDat
90> {
91 pub data: D,
92 pub t: Timestamp,
93}
94
95impl<
96 D: Clone
97 + Debug
98 + Default
99 + ToDat
100 + FromDat
101>
102 Timestamped<D>
103{
104 pub fn new(data: D) -> Outcome<Self> {
105 Ok(Self {
106 data,
107 t: res!(Timestamp::now()),
108 })
109 }
110}
111
112impl<
113 D: Clone
114 + Debug
115 + Default
116 + ToDat
117 + FromDat
118>
119 ToDat for Timestamped<D>
120{
121 fn to_dat(&self) -> Outcome<Dat> {
122 Ok(tup2dat![
123 res!(self.data.to_dat()),
124 res!(self.t.to_dat()),
125 ])
126 }
127}
128
129impl<
130 D: Clone
131 + Debug
132 + Default
133 + ToDat
134 + FromDat
135>
136 FromDat for Timestamped<D>
137{
138 fn from_dat(dat: Dat) -> Outcome<Self> {
139 let mut v = try_extract_tup2dat!(dat);
140 let data = res!(D::from_dat(v[0].extract()));
141 let t = res!(Timestamp::from_dat(v[1].extract()));
142 Ok(Self {
143 data,
144 t,
145 })
146 }
147}