wdext 0.1.0

A DbgEng wrapper framework
// SPDX-FileCopyrightText: 2026 takubokudori
// SPDX-License-Identifier: MIT OR Apache-2.0
use crate::{dbgmodel::*, impl_debug_interface};
use std::rc::Rc;
use windows::Win32::System::Diagnostics::Debug::Extensions::{
    IDataModelConcept, IDataModelConcept_Impl, IDebugHostSymbolEnumerator,
    IDebugHostTypeSignature, IModelObject,
};
use windows_core::{BSTR, Ref, imp::E_POINTER, implement};

pub trait DataModelConceptHandler {
    fn initialize_object(
        &self,
        model_object: ModelObjectRef,
        matching_type_signature: Option<DebugHostTypeSignatureRef>,
        wildcard_matches: Option<DebugHostSymbolEnumeratorRef>,
    ) -> windows::core::Result<()>;
    fn get_name(&self) -> windows::core::Result<String>;
}

impl_debug_interface!(DataModelConcept, DataModelConceptRef, IDataModelConcept);

impl DataModelConceptHandler for DataModelConcept {
    fn initialize_object(
        &self,
        model_object: ModelObjectRef,
        matching_type_signature: Option<DebugHostTypeSignatureRef>,
        wildcard_matches: Option<DebugHostSymbolEnumeratorRef>,
    ) -> windows::core::Result<()> {
        unsafe {
            self.0.InitializeObject(
                model_object.as_raw(),
                matching_type_signature.as_ref().map(|x| x.as_raw()),
                wildcard_matches.as_ref().map(|x| x.as_raw()),
            )
        }
    }
    fn get_name(&self) -> windows_core::Result<String> {
        unsafe { Ok(self.0.GetName()?.to_string()) }
    }
}

#[implement(IDataModelConcept)]
pub struct DataModelConceptAdapter(Rc<dyn DataModelConceptHandler>);

impl DataModelConceptAdapter {
    pub fn new(callbacks: Rc<dyn DataModelConceptHandler>) -> Self {
        Self(callbacks)
    }

    pub fn as_handler(&self) -> &dyn DataModelConceptHandler { self.0.as_ref() }
}

#[allow(non_snake_case)]
impl IDataModelConcept_Impl for DataModelConceptAdapter_Impl {
    fn InitializeObject(
        &self,
        modelObject: Ref<IModelObject>,
        matchingTypeSignature: Ref<IDebugHostTypeSignature>,
        wildcardMatches: Ref<IDebugHostSymbolEnumerator>,
    ) -> windows_core::Result<()> {
        self.0.initialize_object(
            modelObject.as_ref().ok_or(E_POINTER)?.into(),
            matchingTypeSignature.as_ref().map(Into::into),
            wildcardMatches.as_ref().map(Into::into),
        )
    }

    fn GetName(&self) -> windows_core::Result<BSTR> {
        Ok(self.0.get_name()?.into())
    }
}