wdext 0.1.0

A DbgEng wrapper framework
// SPDX-FileCopyrightText: 2026 takubokudori
// SPDX-License-Identifier: MIT OR Apache-2.0
#[cfg(test)]
pub mod tests {
    use crate::tests::util::local_debug2;
    use wdext::*;
    use windows::{Win32::Foundation::S_FALSE, core::imp::S_OK};
    use windy::{ACPStr, ACPString};

    mod util;

    #[test]
    fn test_known_struct_output_ex() {
        known_struct_output_ex!(
            known_struct_output_get_names_impl,
            known_struct_output_suppress_type_name_impl,
            known_struct_output_get_single_line_output_impl
        );

        fn known_struct_output_get_names_impl(
            _client: &WdClient,
        ) -> WdResult<Vec<String>> {
            Ok(vec![
                "name1".to_string(),
                "name2".to_string(),
                "name3".to_string(),
            ])
        }

        fn known_struct_output_suppress_type_name_impl(
            _client: &WdClient,
            type_name: String,
        ) -> WdResult<bool> {
            Ok(type_name != "invalid")
        }

        fn known_struct_output_get_single_line_output_impl(
            _client: &WdClient,
            offset: DebuggeeOffset,
            type_name: String,
        ) -> WdResult<String> {
            Ok(format!("offset={offset:#x}, type_name={type_name}"))
        }

        let ctx = local_debug2();
        let client = ctx.client();
        // Test GetNames
        unsafe {
            let mut buffer = [0xff; 18];
            let mut buffer_chars = buffer.len() as u32;
            assert_eq!(
                KnownStructOutputEx(
                    client.0.as_ptr(),
                    KnownStructFlags::GetNames as u32,
                    0x4649,
                    std::ptr::null_mut(),
                    buffer.as_mut_ptr(),
                    &mut buffer_chars
                ),
                S_FALSE
            );
            assert_eq!(buffer_chars, 19);

            let mut buffer = [0xff; 19];
            let mut buffer_chars = buffer.len() as u32;
            assert_eq!(
                KnownStructOutputEx(
                    client.0.as_ptr(),
                    KnownStructFlags::GetNames as u32,
                    0x4649,
                    std::ptr::null_mut(),
                    buffer.as_mut_ptr(),
                    &mut buffer_chars
                ),
                S_OK
            );
            assert_eq!(ACPStr::from_raw(buffer.as_ptr()).to_string(), "name1");
            assert_eq!(
                ACPStr::from_raw(buffer.as_ptr().add(6)).to_string(),
                "name2"
            );
            assert_eq!(
                ACPStr::from_raw(buffer.as_ptr().add(12)).to_string(),
                "name3"
            );
            assert_eq!(
                ACPStr::from_raw(buffer.as_ptr().add(18)).to_string(),
                ""
            );
        }

        // Test SuppressTypeName
        unsafe {
            let type_name = ACPString::from_utf8("test").unwrap();
            assert_eq!(
                KnownStructOutputEx(
                    client.0.as_ptr(),
                    KnownStructFlags::SuppressTypeName as u32,
                    0x4649,
                    type_name.as_u8_ptr(),
                    std::ptr::null_mut(),
                    std::ptr::null_mut(),
                ),
                S_OK
            );
            let type_name = ACPString::from_utf8("invalid").unwrap();
            assert_eq!(
                KnownStructOutputEx(
                    client.0.as_ptr(),
                    KnownStructFlags::SuppressTypeName as u32,
                    0x4649,
                    type_name.as_u8_ptr(),
                    std::ptr::null_mut(),
                    std::ptr::null_mut(),
                ),
                S_FALSE
            );
        }

        // Test GetSingleLineOutput
        unsafe {
            let mut buffer = [0xff; 29];
            let mut buffer_chars = buffer.len() as u32;
            let type_name = ACPString::from_utf8("test").unwrap();
            assert_eq!(
                KnownStructOutputEx(
                    client.0.as_ptr(),
                    KnownStructFlags::GetSingleLineOutput as u32,
                    0x4649,
                    type_name.as_u8_ptr(),
                    buffer.as_mut_ptr(),
                    &mut buffer_chars
                ),
                S_FALSE
            );
            assert_eq!(buffer_chars, 30);

            let mut buffer = [0xff; 30];
            let mut buffer_chars = buffer.len() as u32;
            assert_eq!(
                KnownStructOutputEx(
                    client.0.as_ptr(),
                    KnownStructFlags::GetSingleLineOutput as u32,
                    0x4649,
                    type_name.as_u8_ptr(),
                    buffer.as_mut_ptr(),
                    &mut buffer_chars
                ),
                S_OK
            );
            assert_eq!(
                ACPStr::from_raw(buffer.as_ptr()).to_string(),
                "offset=0x4649, type_name=test"
            );
        }
    }
}