dfir_windows_types 0.2.4

datatypes to be used to parse Windows data structures
Documentation
use std::{fmt::{Debug, Display}, str::FromStr};

use binrw::{BinRead, BinReaderExt, BinWrite, BinWriterExt};

use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::Error;
#[derive(Deserialize, Serialize, Eq, PartialEq, Copy, Clone, Hash)]
pub struct Guid(Uuid);

impl Guid {
    pub fn from_slice(b: &[u8]) -> Result<Self, Error> {
        Ok(Self(Uuid::from_slice(b)?))
    }
    pub fn from_slice_le(b: &[u8]) -> Result<Self, Error> {
        Ok(Self(Uuid::from_slice_le(b)?))
    }
    pub fn random() -> Self {
        Self(uuid::Uuid::new_v4())
    }
}

impl FromStr for Guid {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(Self(Uuid::from_str(s)?))
    }
}

impl From<Uuid> for Guid {
    fn from(value: Uuid) -> Self {
        Self(value)
    }
}

impl BinRead for Guid {
    type Args<'a> = ();

    fn read_options<R: std::io::Read + std::io::Seek>(
        reader: &mut R,
        endian: binrw::Endian,
        args: Self::Args<'_>,
    ) -> binrw::BinResult<Self> {
        let raw_value: [u8; 16] = reader.read_type_args(endian, args)?;
        let uuid = match endian {
            binrw::Endian::Big => Uuid::from_bytes(raw_value),
            binrw::Endian::Little => Uuid::from_bytes_le(raw_value),
        };
        Ok(Self(uuid))
    }
}

impl BinWrite for Guid {
    type Args<'a> = ();

    fn write_options<W: std::io::Write + std::io::Seek>(
        &self,
        writer: &mut W,
        endian: binrw::Endian,
        args: Self::Args<'_>,
    ) -> binrw::BinResult<()> {
        let value = match endian {
            binrw::Endian::Big => self.0.into_bytes(),
            binrw::Endian::Little => self.0.to_bytes_le(),
        };
        writer.write_type_args(&value, endian, args)
    }
}

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

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

impl<'v> TryFrom<&'v str> for Guid {
    type Error = <uuid::Uuid as std::convert::TryFrom<&'v str>>::Error;

    fn try_from(value: &'v str) -> Result<Self, Self::Error> {
        Ok(Self(Uuid::try_from(value)?))
    }
}