dfirtk_eventdata/
event_level.rs

1use std::{fmt::{Display, Write}, convert::TryFrom};
2
3use anyhow::anyhow;
4use evtx::SerializedEvtxRecord;
5use serde::Serialize;
6use serde_json::Value;
7
8pub enum EventLevel {
9    LogAlways,
10    Critical,
11    Error,
12    Warning,
13    Information,
14    AuditSuccess,
15    AuditFailure,
16}
17
18impl TryFrom<&SerializedEvtxRecord<Value>> for EventLevel {
19    type Error = anyhow::Error;
20
21    fn try_from(
22        value: &SerializedEvtxRecord<Value>,
23    ) -> Result<Self, <EventLevel as TryFrom<&SerializedEvtxRecord<Value>>>::Error> {
24        match value.data["Event"]["System"]["Level"].as_u64() {
25            Some(level_id) => Self::try_from(level_id),
26            None => Err(anyhow!(
27                "missing event level in '{data}'",
28                data = value.data
29            )),
30        }
31    }
32}
33
34impl TryFrom<u64> for EventLevel {
35    type Error = anyhow::Error;
36
37    fn try_from(value: u64) -> Result<Self, <EventLevel as TryFrom<u64>>::Error> {
38        Ok(match value {
39            0 => EventLevel::LogAlways,
40            1 => EventLevel::Critical,
41            2 => EventLevel::Error,
42            3 => EventLevel::Warning,
43            4 => EventLevel::Information,
44            5 => EventLevel::LogAlways,
45            _ => return Err(anyhow!("unknown log level identifier: {value}")),
46        })
47    }
48}
49
50impl Display for EventLevel {
51    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52        match self {
53            EventLevel::LogAlways => f.write_str("âœī¸"),
54            EventLevel::Critical => f.write_char('đŸ’ĸ'),
55            EventLevel::Error => f.write_char('đŸ”Ĩ'),
56            EventLevel::Warning => f.write_str("âš ī¸"),
57            EventLevel::Information => f.write_str("â„šī¸"),
58            EventLevel::AuditSuccess => f.write_char('🙂'),
59            EventLevel::AuditFailure => f.write_char('😡'),
60        }
61    }
62}
63
64impl Serialize for EventLevel {
65    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
66    where
67        S: serde::Serializer,
68    {
69        match self {
70            EventLevel::LogAlways => serializer.serialize_str("âœī¸"),
71            EventLevel::Critical => serializer.serialize_char('đŸ’ĸ'),
72            EventLevel::Error => serializer.serialize_char('đŸ”Ĩ'),
73            EventLevel::Warning => serializer.serialize_str("âš ī¸"),
74            EventLevel::Information => serializer.serialize_str("â„šī¸"),
75            EventLevel::AuditSuccess => serializer.serialize_char('🙂'),
76            EventLevel::AuditFailure => serializer.serialize_char('😡'),
77        }
78    }
79}