dfirtk_eventdata/
related_activity_id.rs

1use std::{fmt::Display, convert::TryFrom};
2
3use evtx::SerializedEvtxRecord;
4use serde_json::Value;
5
6use super::EvtxFieldView;
7
8#[derive(PartialEq, Eq, Clone)]
9pub struct RelatedActivityId<'a>(Option<&'a Value>);
10
11impl<'a> TryFrom<&'a SerializedEvtxRecord<Value>> for RelatedActivityId<'a> {
12    type Error = anyhow::Error;
13
14    fn try_from(record: &'a SerializedEvtxRecord<Value>) -> Result<Self, Self::Error> {
15        let activity_id = &record.data["Event"]["System"]["Correlation"]["#attributes"]["RelatedActivityID"];
16        if activity_id.is_null() {
17            Ok(Self(None))
18        } else {
19            Ok(Self(Some(activity_id)))
20        }
21    }
22}
23
24impl<'a> Display for RelatedActivityId<'a> {
25    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        match self.0.as_ref() {
27            Some(v) => v.fmt(f),
28            None => "None".fmt(f),
29        }
30    }
31}
32
33const GUID_MAX_LENGTH: usize = "F4202F00-1781-44ED-99B9-1FAA35640000".len();
34impl<'a> EvtxFieldView for RelatedActivityId<'a> {
35    fn maximum_display_length(&self) -> usize {
36        GUID_MAX_LENGTH
37    }
38
39    fn value_with_padding(&self) -> String {
40        match self.0 {
41            Some(v) => v.to_string(),
42            None => "                                    ".to_owned(),
43        }
44    }
45}