evtxtools 1.12.1

tools for the analysis of evtx files
Documentation
use std::fmt::Display;

use anyhow::bail;
use evtx::SerializedEvtxRecord;
use serde_json::Value;

use super::EvtxFieldView;

#[derive(PartialEq, Eq, Clone)]
pub struct EventId(u16);

impl TryFrom<&SerializedEvtxRecord<Value>> for EventId {
    type Error = anyhow::Error;

    fn try_from(record: &SerializedEvtxRecord<Value>) -> Result<Self, Self::Error> {
        let event_id = &record.data["Event"]["System"]["EventID"];

        let event_id = match event_id.get("#text") {
            Some(eid) => eid,
            None => event_id,
        };

        if let Some(event_id) = event_id.as_u64() {
            let id: u16 = event_id.try_into()?;
            Ok(Self(id))
        } else {
            bail!("event id cannot be converted to u16: {event_id}")
        }
    }
}

const EVENT_ID_MAX_LENGTH: usize = 5;
impl EvtxFieldView for EventId {
    fn maximum_display_length(&self) -> usize {
        EVENT_ID_MAX_LENGTH
    }

    fn value_with_padding(&self) -> String {
        format!("{:5}", self.0)
    }
}

impl From<EventId> for u16 {
    fn from(me: EventId) -> Self {
        me.0
    }
}

impl From<u16> for EventId {
    fn from(id: u16) -> Self {
        Self(id)
    }
}

impl Display for EventId {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        self.0.fmt(f)
    }
}