falco_event/types/time/
system_time.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use crate::event_derive::{FromBytes, FromBytesResult, ToBytes};
use crate::types::format::Format;
use crate::types::Borrowed;
use chrono::Local;
use std::fmt::Formatter;
use std::io::Write;
use std::time::{Duration, SystemTime, UNIX_EPOCH};

impl FromBytes<'_> for SystemTime {
    fn from_bytes(buf: &mut &[u8]) -> FromBytesResult<Self>
    where
        Self: Sized,
    {
        let duration = Duration::from_bytes(buf)?;
        Ok(UNIX_EPOCH + duration)
    }
}

impl ToBytes for SystemTime {
    fn binary_size(&self) -> usize {
        std::mem::size_of::<u64>()
    }

    fn write<W: Write>(&self, writer: W) -> std::io::Result<()> {
        let duration = self
            .duration_since(UNIX_EPOCH)
            .map_err(|e| std::io::Error::other(e.to_string()))?;
        duration.write(writer)
    }

    fn default_repr() -> impl ToBytes {
        0u64
    }
}

impl Borrowed for SystemTime {
    type Owned = Self;
}

impl<F> Format<F> for SystemTime {
    fn format(&self, fmt: &mut Formatter) -> std::fmt::Result {
        let dt = chrono::DateTime::<Local>::from(*self);
        fmt.write_str(&dt.to_rfc3339_opts(chrono::SecondsFormat::AutoSi, false))
    }
}

#[cfg(test)]
mod tests {
    use std::time::{Duration, SystemTime};

    #[test]
    fn test_serde_systemtime() {
        let st = SystemTime::UNIX_EPOCH + Duration::from_secs(100 * 86400);
        let json = serde_json::to_string(&st).unwrap();

        assert_eq!(
            json,
            r#"{"secs_since_epoch":8640000,"nanos_since_epoch":0}"#
        );
        let st2: SystemTime = serde_json::from_str(&json).unwrap();
        assert_eq!(st, st2);
    }
}