wdext 0.1.0

A DbgEng wrapper framework
// SPDX-FileCopyrightText: 2026 takubokudori
// SPDX-License-Identifier: MIT OR Apache-2.0
use crate::{
    dbgeng::WinResult,
    dbgmodel::{
        DbgModelSymbolKind, DebugHostContext, DebugHostSymbol,
        DebugHostSymbolEnumerator, DebugHostType,
    },
    *,
};

impl_debug_interface!(
    DebugHostModule,
    DebugHostModuleRef,
    IDebugHostModule2,
    IDebugHostModule
);

// Derived from IDebugHostSymbol
impl DebugHostModule {
    pub fn get_context(&self) -> WinResult<DebugHostContext> {
        unsafe { Ok(self.0.GetContext()?.into()) }
    }

    pub fn enumerate_children(
        &self,
        kind: impl Into<DbgModelSymbolKind>,
        name: impl AsRef<WStr>,
    ) -> WinResult<DebugHostSymbolEnumerator> {
        unsafe {
            Ok(self
                .0
                .EnumerateChildren(kind.into().into(), pcw!(name))?
                .into())
        }
    }

    pub fn get_symbol_kind(&self) -> WinResult<DbgModelSymbolKind> {
        unsafe { Ok(self.0.GetSymbolKind()?.into()) }
    }

    pub fn get_name(&self) -> WinResult<WString> {
        unsafe {
            Ok(WString::from_vec_with_nul_unchecked(
                self.0.GetName()?.as_ref(),
            ))
        }
    }

    pub fn get_type(&self) -> WinResult<DebugHostType> {
        unsafe { Ok(self.0.GetType()?.into()) }
    }

    pub fn get_containing_module(&self) -> WinResult<DebugHostModule> {
        unsafe { Ok(self.0.GetContainingModule()?.into()) }
    }

    pub fn compare_against(
        &self,
        comparison_symbol: &DebugHostSymbol, /* comparison_flags: u32 is reserved. */
    ) -> WinResult<bool> {
        unsafe { self.0.CompareAgainst(comparison_symbol.as_raw(), 0) }
    }
}

// IDebugHostModule
impl DebugHostModule {
    pub fn get_image_name(&self, allow_path: bool) -> WinResult<WString> {
        unsafe {
            Ok(WString::from_vec_with_nul_unchecked(
                self.0.GetImageName(allow_path.into())?.as_ref(),
            ))
        }
    }

    pub fn get_base_location(&self) -> WinResult<Location> {
        unsafe { self.0.GetBaseLocation() }
    }

    /// Returns `(fileVersion, productVersion)`.
    pub fn get_version(&self) -> WinResult<(u64, u64)> {
        unsafe {
            let mut file_version = 0;
            let mut product_version = 0;
            self.0.GetVersion(
                Some(&mut file_version),
                Some(&mut product_version),
            )?;
            Ok((file_version, product_version))
        }
    }

    pub fn _get_file_version(&self) -> WinResult<u64> {
        unsafe {
            let mut file_version = 0;
            self.0.GetVersion(Some(&mut file_version), None)?;
            Ok(file_version)
        }
    }

    pub fn _get_product_version(&self) -> WinResult<u64> {
        unsafe {
            let mut product_version = 0;
            self.0.GetVersion(None, Some(&mut product_version))?;
            Ok(product_version)
        }
    }

    pub fn find_type_by_name(
        &self,
        type_name: impl AsRef<WStr>,
    ) -> WinResult<DebugHostType> {
        unsafe { Ok(self.0.FindTypeByName(pcw!(type_name))?.into()) }
    }

    pub fn find_symbol_by_rva(&self, rva: u64) -> WinResult<DebugHostSymbol> {
        unsafe { Ok(self.0.FindSymbolByRVA(rva)?.into()) }
    }

    pub fn find_symbol_by_name(
        &self,
        symbol_name: impl AsRef<WStr>,
    ) -> WinResult<DebugHostSymbol> {
        unsafe { Ok(self.0.FindSymbolByName(pcw!(symbol_name))?.into()) }
    }
}

// IDebugHostModule2
impl DebugHostModule {
    pub fn find_containing_symbol_by_rva(
        &self,
        rva: u64,
    ) -> WinResult<(DebugHostSymbol, DebuggeeOffset)> {
        let mut symbol = None;
        let mut offset = 0;
        unsafe {
            self.0
                .FindContainingSymbolByRVA(rva, &mut symbol, &mut offset)?;
        }

        Ok((symbol.unwrap().into(), offset))
    }
}

// IDebugHostModule3
impl DebugHostModule {
    // GetRange
}

// IDebugHostModule4
impl DebugHostModule {
    // FindTypeByName2
}

// IDebugHostModule5
impl DebugHostModule {
    // GetPrimaryCompilerInformation
}