perl-dap 0.12.1

Debug Adapter Protocol server for Perl
Documentation
//! Request dispatching: handle_request, dispatch_request, response_succeeded_for_command.

use super::*;

impl DebugAdapter {
    pub fn handle_request(
        &mut self,
        request_seq: i64,
        command: &str,
        arguments: Option<Value>,
    ) -> DapMessage {
        eprintln!("DAP request: {} {:?}", command, arguments);

        let response = self.dispatch_request(request_seq, command, arguments);

        // Preserve existing direct-call behavior for tests and in-memory usage.
        if command == "initialize" && Self::response_succeeded_for_command(&response, "initialize")
        {
            self.send_event("initialized", None);
        }

        response
    }

    /// Handle a DAP request (mock version for testing)
    pub fn handle_request_mock(
        &mut self,
        request_seq: i64,
        command: &str,
        arguments: Option<Value>,
    ) -> DapMessage {
        eprintln!("DAP request (mock): {} {:?}", command, arguments);

        if command == "attach" {
            let seq = self.next_seq();
            return DapMessage::Response {
                seq,
                request_seq,
                success: false,
                command: "attach".to_string(),
                body: None,
                message: Some("Attach not yet fully implemented".to_string()),
            };
        }

        let response = self.dispatch_request(request_seq, command, arguments);
        if command == "initialize" && Self::response_succeeded_for_command(&response, "initialize")
        {
            self.send_event("initialized", None);
        }
        response
    }

    pub(super) fn dispatch_request(
        &mut self,
        request_seq: i64,
        command: &str,
        arguments: Option<Value>,
    ) -> DapMessage {
        let seq = self.next_seq();

        match command {
            "initialize" => self.handle_initialize(seq, request_seq, arguments),
            "launch" => self.handle_launch(seq, request_seq, arguments),
            "attach" => self.handle_attach(seq, request_seq, arguments),
            "disconnect" => self.handle_disconnect(seq, request_seq, arguments),
            "terminate" => self.handle_terminate(seq, request_seq, arguments),
            "setBreakpoints" => self.handle_set_breakpoints(seq, request_seq, arguments),
            "setFunctionBreakpoints" => {
                self.handle_set_function_breakpoints(seq, request_seq, arguments)
            }
            "setExceptionBreakpoints" => {
                self.handle_set_exception_breakpoints(seq, request_seq, arguments)
            }
            "configurationDone" => self.handle_configuration_done(seq, request_seq),
            "threads" => self.handle_threads(seq, request_seq),
            "stackTrace" => self.handle_stack_trace(seq, request_seq, arguments),
            "scopes" => self.handle_scopes(seq, request_seq, arguments),
            "variables" => self.handle_variables(seq, request_seq, arguments),
            "setVariable" => self.handle_set_variable(seq, request_seq, arguments),
            "continue" => self.handle_continue(seq, request_seq, arguments),
            "next" => self.handle_next(seq, request_seq, arguments),
            "stepIn" => self.handle_step_in(seq, request_seq, arguments),
            "stepOut" => self.handle_step_out(seq, request_seq, arguments),
            "pause" => self.handle_pause(seq, request_seq, arguments),
            "evaluate" => self.handle_evaluate(seq, request_seq, arguments),
            "inlineValues" => self.handle_inline_values(seq, request_seq, arguments),
            "breakpointLocations" => self.handle_breakpoint_locations(seq, request_seq, arguments),
            "source" => self.handle_source(seq, request_seq, arguments),
            "loadedSources" => self.handle_loaded_sources(seq, request_seq, arguments),
            "modules" => self.handle_modules(seq, request_seq, arguments),
            "completions" => self.handle_completions(seq, request_seq, arguments),
            "exceptionInfo" => self.handle_exception_info(seq, request_seq, arguments),
            "restart" => self.handle_restart(seq, request_seq, arguments),
            "setExpression" => self.handle_set_expression(seq, request_seq, arguments),
            "dataBreakpointInfo" => self.handle_data_breakpoint_info(seq, request_seq, arguments),
            "setDataBreakpoints" => self.handle_set_data_breakpoints(seq, request_seq, arguments),
            "cancel" => self.handle_cancel(seq, request_seq, arguments),
            "stepInTargets" => self.handle_step_in_targets(seq, request_seq, arguments),
            "gotoTargets" => self.handle_goto_targets(seq, request_seq, arguments),
            "goto" => self.handle_goto(seq, request_seq, arguments),
            "restartFrame" => self.handle_restart_frame(seq, request_seq, arguments),
            "terminateThreads" => self.handle_terminate_threads(seq, request_seq, arguments),
            _ => DapMessage::Response {
                seq,
                request_seq,
                success: false,
                command: command.to_string(),
                body: None,
                message: Some(format!("Unknown command: {}", command)),
            },
        }
    }

    pub(super) fn response_succeeded_for_command(
        response: &DapMessage,
        expected_command: &str,
    ) -> bool {
        matches!(
            response,
            DapMessage::Response {
                success: true,
                command,
                ..
            } if command == expected_command
        )
    }
}