wdext 0.1.0

A DbgEng wrapper framework
// SPDX-FileCopyrightText: 2026 takubokudori
// SPDX-License-Identifier: MIT OR Apache-2.0
//! IDebugInputCallbacks

use crate::{impl_callbacks_catch_unwind, impl_debug_interface};
use std::{cell::Cell, rc::Rc};
use windows::Win32::System::Diagnostics::Debug::Extensions::*;
use windows_core::implement;

/// Trait for IDebugInputCallbacks.
#[allow(unused_variables)]
pub trait DebugInputCallbacksHandler {
    fn start_input(&self, buffer_size: u32) -> windows::core::Result<()> {
        Ok(())
    }

    fn end_input(&self) -> windows::core::Result<()> { Ok(()) }
}

impl_debug_interface!(
    DebugInputCallbacks,
    DebugInputCallbacksRef,
    IDebugInputCallbacks
);

impl From<DebugInputCallbacks> for IDebugInputCallbacks {
    fn from(value: DebugInputCallbacks) -> Self { value.0 }
}

impl DebugInputCallbacksHandler for DebugInputCallbacks {
    fn start_input(&self, buffer_size: u32) -> windows::core::Result<()> {
        unsafe { self.0.StartInput(buffer_size) }
    }

    fn end_input(&self) -> windows::core::Result<()> {
        unsafe { self.0.EndInput() }
    }
}

#[implement(IDebugInputCallbacks)]
pub struct DebugInputCallbacksAdapter {
    pub callbacks: Rc<dyn DebugInputCallbacksHandler>,
    poisoned: Cell<bool>,
}

impl DebugInputCallbacksAdapter {
    pub fn new(callbacks: Rc<dyn DebugInputCallbacksHandler>) -> Self {
        Self {
            callbacks,
            poisoned: Cell::new(false),
        }
    }

    pub fn as_handler(&self) -> &dyn DebugInputCallbacksHandler {
        self.callbacks.as_ref()
    }

    pub fn into_callbacks(self) -> DebugInputCallbacks {
        let interface: IDebugInputCallbacks = self.into();
        interface.into()
    }

    impl_callbacks_catch_unwind!();
}

#[allow(non_snake_case)]
impl IDebugInputCallbacks_Impl for DebugInputCallbacksAdapter_Impl {
    fn StartInput(&self, buffer_size: u32) -> windows::core::Result<()> {
        self.__catch_unwind(|| self.callbacks.start_input(buffer_size))
    }

    fn EndInput(&self) -> windows::core::Result<()> {
        self.__catch_unwind(|| self.callbacks.end_input())
    }
}