use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Deserialize)]
pub struct DapMessage {
pub seq: i64,
#[serde(rename = "type")]
pub msg_type: String,
pub command: Option<String>,
pub arguments: Option<Value>,
pub request_seq: Option<i64>,
pub success: Option<bool>,
pub message: Option<String>,
pub body: Option<Value>,
}
#[derive(Debug, Serialize)]
pub struct DapResponse {
pub seq: i64,
#[serde(rename = "type")]
pub msg_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub request_seq: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub success: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub command: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub body: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub event: Option<String>,
}
impl DapResponse {
pub fn success(seq: i64, request_seq: i64, command: &str, body: Option<Value>) -> Self {
Self {
seq,
msg_type: "response".to_string(),
request_seq: Some(request_seq),
success: Some(true),
command: Some(command.to_string()),
message: None,
body,
event: None,
}
}
pub fn event(seq: i64, event: &str, body: Option<Value>) -> Self {
Self {
seq,
msg_type: "event".to_string(),
request_seq: None,
success: None,
command: None,
message: None,
body,
event: Some(event.to_string()),
}
}
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Capabilities {
pub supports_configuration_done_request: bool,
pub supports_evaluate_for_hovers: bool,
pub supports_step_in_targets_request: bool,
pub supports_set_variable: bool,
pub supports_set_expression: bool,
pub supports_conditional_breakpoints: bool,
pub supports_hit_conditional_breakpoints: bool,
pub supports_log_points: bool,
pub supports_function_breakpoints: bool,
pub supports_restart_frame: bool,
pub supports_exception_breakpoint_filters: bool,
pub supports_terminate_request: bool,
pub supports_cancel_request: bool,
#[serde(rename = "supportsCompletionsRequest")]
pub supports_completions_request: bool,
#[serde(rename = "supportsInvalidatedEvent")]
pub supports_invalidated_event: bool,
pub supports_harn_host_call: bool,
pub supports_burin_prompt_provenance: bool,
pub exception_breakpoint_filters: Vec<ExceptionBreakpointFilter>,
}
impl Default for Capabilities {
fn default() -> Self {
Self {
supports_configuration_done_request: true,
supports_evaluate_for_hovers: true,
supports_step_in_targets_request: true,
supports_set_variable: true,
supports_set_expression: true,
supports_conditional_breakpoints: true,
supports_hit_conditional_breakpoints: true,
supports_log_points: true,
supports_function_breakpoints: true,
supports_restart_frame: true,
supports_exception_breakpoint_filters: true,
supports_terminate_request: true,
supports_cancel_request: true,
supports_completions_request: true,
supports_invalidated_event: true,
supports_harn_host_call: true,
supports_burin_prompt_provenance: true,
exception_breakpoint_filters: vec![
ExceptionBreakpointFilter {
filter: "all".to_string(),
label: "All Exceptions".to_string(),
default: false,
},
ExceptionBreakpointFilter {
filter: "tool_error".to_string(),
label: "Tool errors".to_string(),
default: false,
},
ExceptionBreakpointFilter {
filter: "llm_refusal".to_string(),
label: "LLM refusals".to_string(),
default: false,
},
ExceptionBreakpointFilter {
filter: "budget_exceeded".to_string(),
label: "Budget exhausted / loop stuck".to_string(),
default: false,
},
ExceptionBreakpointFilter {
filter: "parse_failure".to_string(),
label: "Parse failures".to_string(),
default: false,
},
],
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExceptionBreakpointFilter {
pub filter: String,
pub label: String,
pub default: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FunctionBreakpoint {
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub condition: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "hitCondition"
)]
pub hit_condition: Option<String>,
#[serde(default)]
pub id: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Breakpoint {
pub id: i64,
pub verified: bool,
pub line: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<Source>,
#[serde(skip_serializing_if = "Option::is_none")]
pub condition: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "hitCondition")]
pub hit_condition: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "logMessage")]
pub log_message: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "triggeredBy"
)]
pub triggered_by: Option<Vec<i64>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Source {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option<String>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StackFrame {
pub id: i64,
pub name: String,
pub line: i64,
pub column: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<Source>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Scope {
pub name: String,
pub variables_reference: i64,
pub expensive: bool,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Variable {
pub name: String,
pub value: String,
#[serde(rename = "type")]
pub var_type: String,
pub variables_reference: i64,
}