evtc\content/
guid.rs

1use std::mem;
2pub use windows_core::GUID;
3
4/// Extensions for [`GUID`].
5pub trait GuidExt {
6    /// Formats the GUID as a simple hex string.
7    fn format_simple(&self) -> String;
8
9    /// Formats the GUID as a hyphenated hex string.
10    fn format_hyphenated(&self) -> String;
11
12    /// Returns the contained GUID **misinterpreted** as raw bytes.
13    ///
14    /// Some GW2 community projects misinterpret the memory layout of the GUID as bytes rather than a Windows [`GUID`].
15    /// This is helpful when comparing or interfacing with such projects.
16    ///
17    /// # Safety
18    /// The returned bytes represent the memory of the underlying Windows [`GUID`] struct.
19    /// They do not represent the actual GUID.
20    /// Constructing a GUID with them will result in a different GUID than the original.
21    ///
22    /// To get the correct bytes you can convert the GUID to a [`u128`] and then to bytes.
23    unsafe fn misinterpret(&self) -> [u8; 16];
24}
25
26impl GuidExt for GUID {
27    #[inline]
28    fn format_simple(&self) -> String {
29        format!("{:0>32X}", self.to_u128())
30    }
31
32    #[inline]
33    fn format_hyphenated(&self) -> String {
34        format!("{self:?}")
35    }
36
37    #[inline]
38    unsafe fn misinterpret(&self) -> [u8; 16] {
39        mem::transmute::<GUID, [u8; 16]>(*self)
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46    use crate::{content::ContentInfo, Event, StateChange, TryExtract};
47    use std::mem;
48
49    #[test]
50    fn extract() {
51        let event = Event {
52            is_statechange: StateChange::IdToGUID.into(),
53            src_agent: 4820869827943421467,
54            dst_agent: 11091919494850445953,
55            skill_id: 446,
56            overstack_value: 0,
57            ..unsafe { mem::zeroed() }
58        };
59        assert_eq!(event.src_agent, 0x42E72B9102F7561B);
60        assert_eq!(event.dst_agent, 0x99EE6A0357CA8281);
61
62        let info = ContentInfo::try_extract(&event).expect("failed to extract");
63        assert_eq!(
64            info.guid,
65            GUID::from_u128(0x02F7561B_2B91_42E7_8182_CA57036AEE99)
66        );
67    }
68
69    #[test]
70    fn guid_format() {
71        let guid = GUID::from_u128(0x02F7561B_2B91_42E7_8182_CA57036AEE99);
72
73        assert_eq!(guid.format_simple(), "02F7561B2B9142E78182CA57036AEE99");
74        assert_eq!(
75            guid.format_hyphenated(),
76            "02F7561B-2B91-42E7-8182-CA57036AEE99"
77        );
78    }
79}