dap_reactor/
models.rs

1mod attach;
2mod breakpoint_locations;
3mod configuration_done;
4mod r#continue;
5mod disconnect;
6mod evaluate;
7mod exception_info;
8mod goto;
9mod initialize;
10mod launch;
11mod loaded_sources;
12mod next;
13mod restart;
14mod reverse_continue;
15mod scopes;
16mod set_breakpoints;
17mod stack_trace;
18mod step_back;
19mod terminate;
20mod threads;
21mod variables;
22
23pub use attach::*;
24pub use breakpoint_locations::*;
25pub use configuration_done::*;
26pub use disconnect::*;
27pub use evaluate::*;
28pub use exception_info::*;
29pub use goto::*;
30pub use initialize::*;
31pub use launch::*;
32pub use loaded_sources::*;
33pub use next::*;
34pub use r#continue::*;
35pub use restart::*;
36pub use reverse_continue::*;
37pub use scopes::*;
38pub use set_breakpoints::*;
39pub use stack_trace::*;
40pub use step_back::*;
41pub use terminate::*;
42pub use threads::*;
43pub use variables::*;
44
45use crate::error::{Cause, Error};
46use crate::utils;
47
48use serde_json::{json, Map, Value};
49
50use std::collections::HashMap;
51
52#[derive(Debug, Clone, PartialEq, Eq)]
53pub struct Message {
54    pub id: u64,
55    pub format: String,
56    pub variables: Option<HashMap<String, String>>,
57    pub send_telemetry: bool,
58    pub show_user: bool,
59    pub url: Option<String>,
60    pub url_label: Option<String>,
61}
62
63#[derive(Debug, Clone, PartialEq, Eq, Hash)]
64pub struct Checksum {
65    pub algorithm: ChecksumAlgorithm,
66    pub checksum: String,
67}
68
69#[derive(Debug, Clone, PartialEq, Eq, Hash)]
70pub enum SourceReference {
71    Path(String),
72    Reference(u32),
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
76pub enum SourcePresentationHint {
77    Normal,
78    Emphasize,
79    Deemphasize,
80}
81
82#[derive(Debug, Clone, PartialEq, Eq)]
83pub struct Source {
84    pub name: Option<String>,
85    pub source_reference: Option<SourceReference>,
86    pub presentation_hint: Option<SourcePresentationHint>,
87    pub origin: Option<String>,
88    pub sources: Vec<Source>,
89    pub adapter_data: Option<Value>,
90    pub checksums: Vec<Checksum>,
91}
92
93#[derive(Debug, Clone, PartialEq, Eq)]
94pub struct Breakpoint {
95    pub id: Option<u64>,
96    pub verified: bool,
97    pub message: Option<String>,
98    pub source: Option<Source>,
99    pub line: Option<u64>,
100    pub column: Option<u64>,
101    pub end_line: Option<u64>,
102    pub end_column: Option<u64>,
103    pub instruction_reference: Option<String>,
104    pub offset: Option<i64>,
105}
106
107#[derive(Debug, Clone, PartialEq, Eq)]
108pub struct Capabilities {
109    pub supports_configuration_done_request: bool,
110    pub supports_function_breakpoints: bool,
111    pub supports_conditional_breakpoints: bool,
112    pub supports_hit_conditional_breakpoints: bool,
113    pub supports_evaluate_for_hovers: bool,
114    pub exception_breakpoint_filters: Vec<ExceptionBreakpointsFilter>,
115    pub supports_step_back: bool,
116    pub supports_set_variable: bool,
117    pub supports_restart_frame: bool,
118    pub supports_goto_targets_request: bool,
119    pub supports_step_in_targets_request: bool,
120    pub supports_completions_request: bool,
121    pub completion_trigger_characters: Vec<String>,
122    pub supports_modules_request: bool,
123    pub additional_module_columns: Vec<ColumnDescriptor>,
124    pub supported_checksum_algorithms: Vec<ChecksumAlgorithm>,
125    pub supports_restart_request: bool,
126    pub supports_exception_options: bool,
127    pub supports_value_formatting_options: bool,
128    pub supports_exception_info_request: bool,
129    pub support_terminate_debuggee: bool,
130    pub support_suspend_debuggee: bool,
131    pub supports_delayed_stack_trace_loading: bool,
132    pub supports_loaded_sources_request: bool,
133    pub supports_log_points: bool,
134    pub supports_terminate_threads_request: bool,
135    pub supports_set_expression: bool,
136    pub supports_terminate_request: bool,
137    pub supports_data_breakpoints: bool,
138    pub supports_read_memory_request: bool,
139    pub supports_write_memory_request: bool,
140    pub supports_disassemble_request: bool,
141    pub supports_cancel_request: bool,
142    pub supports_breakpoint_locations_request: bool,
143    pub supports_clipboard_context: bool,
144    pub supports_stepping_granularity: bool,
145    pub supports_instruction_breakpoints: bool,
146    pub supports_exception_filter_options: bool,
147    pub supports_single_thread_execution_requests: bool,
148}
149
150#[derive(Debug, Clone, Copy, PartialEq, Eq)]
151pub enum ColumnDescriptorType {
152    String,
153    Number,
154    Boolean,
155    UnixTimestampUTC,
156}
157
158#[derive(Debug, Clone, PartialEq, Eq)]
159pub struct ColumnDescriptor {
160    pub attribute_name: String,
161    pub label: String,
162    pub format: Option<String>,
163    pub ty: Option<ColumnDescriptorType>,
164    pub width: Option<u64>,
165}
166
167#[derive(Debug, Clone, PartialEq, Eq)]
168pub struct ExceptionBreakpointsFilter {
169    pub filter: String,
170    pub label: String,
171    pub description: Option<String>,
172    pub default: bool,
173    pub supports_condition: bool,
174    pub condition_description: Option<String>,
175}
176
177#[derive(Debug, Clone, PartialEq, Eq)]
178pub enum StackFrameModuleId {
179    Number(u64),
180    String(String),
181}
182
183#[derive(Debug, Clone, Copy, PartialEq, Eq)]
184pub enum StackFramePresentationHint {
185    Normal,
186    Label,
187    Subtle,
188}
189
190#[derive(Debug, Clone, PartialEq, Eq)]
191pub struct StackFrame {
192    pub id: u64,
193    pub name: String,
194    pub source: Option<Source>,
195    pub line: u64,
196    pub column: u64,
197    pub end_line: Option<u64>,
198    pub end_column: Option<u64>,
199    pub can_restart: bool,
200    pub instruction_pointer_reference: Option<String>,
201    pub module_id: Option<StackFrameModuleId>,
202    pub presentation_hint: Option<StackFramePresentationHint>,
203}
204
205#[derive(Debug, Clone, Copy, PartialEq, Eq)]
206pub struct StackFrameFormat {
207    pub parameters: bool,
208    pub parameter_types: bool,
209    pub parameter_names: bool,
210    pub parameter_values: bool,
211    pub line: bool,
212    pub module: bool,
213    pub include_all: bool,
214}
215
216#[derive(Debug, Clone, Copy, PartialEq, Eq)]
217pub struct ValueFormat {
218    pub hex: bool,
219}
220
221impl From<Message> for Value {
222    fn from(message: Message) -> Self {
223        let Message {
224            id,
225            format,
226            variables,
227            send_telemetry,
228            show_user,
229            url,
230            url_label,
231        } = message;
232
233        let id = utils::attribute_u64("id", id);
234        let format = utils::attribute_string("format", format);
235        let variables = utils::attribute_map_optional("variables", variables);
236        let send_telemetry = utils::attribute_bool_optional("sendTelemetry", send_telemetry);
237        let show_user = utils::attribute_bool_optional("showUser", show_user);
238        let url = utils::attribute_string_optional("url", url);
239        let url_label = utils::attribute_string_optional("urlLabel", url_label);
240
241        utils::finalize_object(
242            id.chain(format)
243                .chain(variables)
244                .chain(send_telemetry)
245                .chain(show_user)
246                .chain(url)
247                .chain(url_label),
248        )
249    }
250}
251
252impl TryFrom<&Map<String, Value>> for Message {
253    type Error = Error;
254
255    fn try_from(map: &Map<String, Value>) -> Result<Self, Self::Error> {
256        let id = utils::get_u64(map, "id")?;
257        let format = utils::get_string(map, "format")?;
258        let variables = utils::get_map_to_string_optional(map, "variables")?;
259        let send_telemetry = utils::get_bool_optional(map, "sendTelemetry")?;
260        let show_user = utils::get_bool_optional(map, "showUser")?;
261        let url = utils::get_string_optional(map, "url")?;
262        let url_label = utils::get_string_optional(map, "urlLabel")?;
263
264        Ok(Self {
265            id,
266            format,
267            variables,
268            send_telemetry,
269            show_user,
270            url,
271            url_label,
272        })
273    }
274}
275
276impl From<Checksum> for Value {
277    fn from(c: Checksum) -> Self {
278        json!({
279            "algorithm": Value::String(<&'static str>::from(c.algorithm).into()),
280            "checksum": Value::String(c.checksum),
281        })
282    }
283}
284
285impl TryFrom<&Map<String, Value>> for Checksum {
286    type Error = Error;
287
288    fn try_from(map: &Map<String, Value>) -> Result<Self, Self::Error> {
289        let algorithm = utils::get_str(map, "algorithm").and_then(ChecksumAlgorithm::try_from)?;
290        let checksum = utils::get_string(map, "checksum")?;
291
292        Ok(Self {
293            algorithm,
294            checksum,
295        })
296    }
297}
298
299impl From<SourcePresentationHint> for &'static str {
300    fn from(p: SourcePresentationHint) -> Self {
301        match p {
302            SourcePresentationHint::Normal => "normal",
303            SourcePresentationHint::Emphasize => "emphasize",
304            SourcePresentationHint::Deemphasize => "deemphasize",
305        }
306    }
307}
308
309impl From<SourcePresentationHint> for String {
310    fn from(s: SourcePresentationHint) -> Self {
311        <&'static str>::from(s).into()
312    }
313}
314
315impl TryFrom<&str> for SourcePresentationHint {
316    type Error = Error;
317
318    fn try_from(s: &str) -> Result<Self, Self::Error> {
319        match s {
320            "normal" => Ok(SourcePresentationHint::Normal),
321            "emphasize" => Ok(SourcePresentationHint::Emphasize),
322            "deemphasize" => Ok(SourcePresentationHint::Deemphasize),
323            _ => Err(Error::new("sourcePresentationHint", Cause::ExpectsEnum)),
324        }
325    }
326}
327
328impl From<Source> for Value {
329    fn from(source: Source) -> Self {
330        let Source {
331            name,
332            source_reference,
333            presentation_hint,
334            origin,
335            sources,
336            adapter_data,
337            checksums,
338        } = source;
339
340        let (path, source_reference) = source_reference
341            .map(|r| match r {
342                SourceReference::Path(path) => (Some(path), None),
343                SourceReference::Reference(n) if n == 0 => (None, None),
344                SourceReference::Reference(n) => (None, Some(n)),
345            })
346            .unwrap_or((None, None));
347
348        let name = utils::attribute_string_optional("name", name);
349        let path = utils::attribute_string_optional("path", path);
350        let source_reference = utils::attribute_u32_optional("sourceReference", source_reference);
351        let presentation_hint =
352            utils::attribute_string_optional("presentationHint", presentation_hint);
353        let origin = utils::attribute_string_optional("origin", origin);
354        let sources = utils::attribute_array_optional("sources", sources);
355        let adapter_data = utils::attribute_optional("adapterData", adapter_data);
356        let checksums = utils::attribute_array_optional("checksums", checksums);
357
358        utils::finalize_object(
359            name.chain(path)
360                .chain(source_reference)
361                .chain(presentation_hint)
362                .chain(origin)
363                .chain(sources)
364                .chain(adapter_data)
365                .chain(checksums),
366        )
367    }
368}
369
370impl TryFrom<&Map<String, Value>> for Source {
371    type Error = Error;
372
373    fn try_from(map: &Map<String, Value>) -> Result<Self, Self::Error> {
374        let name = utils::get_string_optional(map, "name")?;
375
376        let path = utils::get_string_optional(map, "path")?.map(SourceReference::Path);
377        let source_reference = utils::get_u32_optional(map, "sourceReference")?
378            .filter(|n| n > &0)
379            .map(SourceReference::Reference);
380
381        let source_reference = source_reference.or(path);
382
383        let presentation_hint = utils::get_str_optional(map, "presentationHint")?
384            .map(SourcePresentationHint::try_from)
385            .transpose()?;
386
387        let origin = utils::get_string_optional(map, "origin")?;
388        let sources = utils::get_array_optional(map, "sources")?;
389        let adapter_data = map.get("adapterData").cloned();
390        let checksums = utils::get_array_optional(map, "checksums")?;
391
392        Ok(Self {
393            name,
394            source_reference,
395            presentation_hint,
396            origin,
397            sources,
398            adapter_data,
399            checksums,
400        })
401    }
402}
403
404impl From<Breakpoint> for Value {
405    fn from(breakpoint: Breakpoint) -> Self {
406        let Breakpoint {
407            id,
408            verified,
409            message,
410            source,
411            line,
412            column,
413            end_line,
414            end_column,
415            instruction_reference,
416            offset,
417        } = breakpoint;
418
419        let id = utils::attribute_u64_optional("id", id);
420        let verified = utils::attribute_bool("verified", verified);
421        let message = utils::attribute_string_optional("message", message);
422        let source = utils::attribute_optional("source", source);
423        let line = utils::attribute_u64_optional("line", line);
424        let column = utils::attribute_u64_optional("column", column);
425        let end_line = utils::attribute_u64_optional("endLine", end_line);
426        let end_column = utils::attribute_u64_optional("endColumn", end_column);
427        let instruction_reference =
428            utils::attribute_string_optional("instructionReference", instruction_reference);
429        let offset = utils::attribute_i64_optional("offset", offset);
430
431        utils::finalize_object(
432            id.chain(verified)
433                .chain(message)
434                .chain(source)
435                .chain(line)
436                .chain(column)
437                .chain(end_line)
438                .chain(end_column)
439                .chain(instruction_reference)
440                .chain(offset),
441        )
442    }
443}
444
445impl TryFrom<&Map<String, Value>> for Breakpoint {
446    type Error = Error;
447
448    fn try_from(map: &Map<String, Value>) -> Result<Self, Self::Error> {
449        let id = utils::get_u64_optional(map, "id")?;
450        let verified = utils::get_bool(map, "verified")?;
451        let message = utils::get_string_optional(map, "message")?;
452        let source = utils::get_object_optional(map, "source")?;
453        let line = utils::get_u64_optional(map, "line")?;
454        let column = utils::get_u64_optional(map, "column")?;
455        let end_line = utils::get_u64_optional(map, "endLine")?;
456        let end_column = utils::get_u64_optional(map, "endColumn")?;
457        let instruction_reference = utils::get_string_optional(map, "instructionReference")?;
458        let offset = utils::get_i64_optional(map, "endColumn")?;
459
460        Ok(Self {
461            id,
462            verified,
463            message,
464            source,
465            line,
466            column,
467            end_line,
468            end_column,
469            instruction_reference,
470            offset,
471        })
472    }
473}
474
475impl From<ExceptionBreakpointsFilter> for Value {
476    fn from(filter: ExceptionBreakpointsFilter) -> Self {
477        let ExceptionBreakpointsFilter {
478            filter,
479            label,
480            description,
481            default,
482            supports_condition,
483            condition_description,
484        } = filter;
485
486        let filter = utils::attribute_string("filter", filter);
487        let label = utils::attribute_string("label", label);
488        let description = utils::attribute_string_optional("description", description);
489        let default = utils::attribute_bool_optional("default", default);
490        let supports_condition =
491            utils::attribute_bool_optional("supportsCondition", supports_condition);
492        let condition_description =
493            utils::attribute_string_optional("conditionDescription", condition_description);
494
495        utils::finalize_object(
496            filter
497                .chain(label)
498                .chain(description)
499                .chain(default)
500                .chain(supports_condition)
501                .chain(condition_description),
502        )
503    }
504}
505
506impl TryFrom<&Map<String, Value>> for ExceptionBreakpointsFilter {
507    type Error = Error;
508
509    fn try_from(map: &Map<String, Value>) -> Result<Self, Self::Error> {
510        let filter = utils::get_string(map, "filter")?;
511        let label = utils::get_string(map, "label")?;
512        let description = utils::get_string_optional(map, "description")?;
513        let default = utils::get_bool_optional(map, "default")?;
514        let supports_condition = utils::get_bool_optional(map, "supportsCondition")?;
515        let condition_description = utils::get_string_optional(map, "conditionDescription")?;
516
517        Ok(Self {
518            filter,
519            label,
520            description,
521            default,
522            supports_condition,
523            condition_description,
524        })
525    }
526}
527
528impl From<ColumnDescriptorType> for &'static str {
529    fn from(t: ColumnDescriptorType) -> Self {
530        match t {
531            ColumnDescriptorType::String => "string",
532            ColumnDescriptorType::Number => "number",
533            ColumnDescriptorType::Boolean => "boolean",
534            ColumnDescriptorType::UnixTimestampUTC => "unixTimestampUTC",
535        }
536    }
537}
538
539impl From<ColumnDescriptorType> for String {
540    fn from(t: ColumnDescriptorType) -> Self {
541        <&'static str>::from(t).into()
542    }
543}
544
545impl TryFrom<&str> for ColumnDescriptorType {
546    type Error = Error;
547
548    fn try_from(s: &str) -> Result<Self, Self::Error> {
549        match s {
550            "string" => Ok(Self::String),
551            "number" => Ok(Self::Number),
552            "boolean" => Ok(Self::Boolean),
553            "unixTimestampUTC" => Ok(Self::UnixTimestampUTC),
554            _ => Err(Error::new("columnDescriptorType", Cause::ExpectsEnum)),
555        }
556    }
557}
558
559impl From<ColumnDescriptor> for Value {
560    fn from(d: ColumnDescriptor) -> Self {
561        let ColumnDescriptor {
562            attribute_name,
563            label,
564            format,
565            ty,
566            width,
567        } = d;
568
569        let attribute_name = utils::attribute_string("attributeName", attribute_name);
570        let label = utils::attribute_string("label", label);
571        let format = utils::attribute_string_optional("format", format);
572        let ty = utils::attribute_string_optional("type", ty);
573        let width = utils::attribute_u64_optional("width", width);
574
575        utils::finalize_object(
576            attribute_name
577                .chain(label)
578                .chain(format)
579                .chain(ty)
580                .chain(width),
581        )
582    }
583}
584
585impl TryFrom<&Map<String, Value>> for ColumnDescriptor {
586    type Error = Error;
587
588    fn try_from(map: &Map<String, Value>) -> Result<Self, Self::Error> {
589        let attribute_name = utils::get_string(map, "attributeName")?;
590        let label = utils::get_string(map, "label")?;
591        let format = utils::get_string_optional(map, "format")?;
592        let ty = utils::get_str_optional(map, "type")?
593            .map(ColumnDescriptorType::try_from)
594            .transpose()?;
595        let width = utils::get_u64_optional(map, "width")?;
596
597        Ok(Self {
598            attribute_name,
599            label,
600            format,
601            ty,
602            width,
603        })
604    }
605}
606
607impl From<Capabilities> for Value {
608    fn from(c: Capabilities) -> Self {
609        let Capabilities {
610            supports_configuration_done_request,
611            supports_function_breakpoints,
612            supports_conditional_breakpoints,
613            supports_hit_conditional_breakpoints,
614            supports_evaluate_for_hovers,
615            exception_breakpoint_filters,
616            supports_step_back,
617            supports_set_variable,
618            supports_restart_frame,
619            supports_goto_targets_request,
620            supports_step_in_targets_request,
621            supports_completions_request,
622            completion_trigger_characters,
623            supports_modules_request,
624            additional_module_columns,
625            supported_checksum_algorithms,
626            supports_restart_request,
627            supports_exception_options,
628            supports_value_formatting_options,
629            supports_exception_info_request,
630            support_terminate_debuggee,
631            support_suspend_debuggee,
632            supports_delayed_stack_trace_loading,
633            supports_loaded_sources_request,
634            supports_log_points,
635            supports_terminate_threads_request,
636            supports_set_expression,
637            supports_terminate_request,
638            supports_data_breakpoints,
639            supports_read_memory_request,
640            supports_write_memory_request,
641            supports_disassemble_request,
642            supports_cancel_request,
643            supports_breakpoint_locations_request,
644            supports_clipboard_context,
645            supports_stepping_granularity,
646            supports_instruction_breakpoints,
647            supports_exception_filter_options,
648            supports_single_thread_execution_requests,
649        } = c;
650
651        let supports_configuration_done_request = utils::attribute_bool_optional(
652            "supportsConfigurationDoneRequest",
653            supports_configuration_done_request,
654        );
655        let supports_function_breakpoints = utils::attribute_bool_optional(
656            "supportsFunctionBreakpoints",
657            supports_function_breakpoints,
658        );
659        let supports_conditional_breakpoints = utils::attribute_bool_optional(
660            "supportsConditionalBreakpoints",
661            supports_conditional_breakpoints,
662        );
663        let supports_hit_conditional_breakpoints = utils::attribute_bool_optional(
664            "supportsHitConditionalBreakpoints",
665            supports_hit_conditional_breakpoints,
666        );
667        let supports_evaluate_for_hovers = utils::attribute_bool_optional(
668            "supportsEvaluateForHovers",
669            supports_evaluate_for_hovers,
670        );
671        let exception_breakpoint_filters = utils::attribute_array_optional(
672            "exceptionBreakpointFilters",
673            exception_breakpoint_filters,
674        );
675        let supports_step_back =
676            utils::attribute_bool_optional("supportsStepBack", supports_step_back);
677        let supports_set_variable =
678            utils::attribute_bool_optional("supportsSetVariable", supports_set_variable);
679        let supports_restart_frame =
680            utils::attribute_bool_optional("supportsRestartFrame", supports_restart_frame);
681        let supports_goto_targets_request = utils::attribute_bool_optional(
682            "supportsGotoTargetsRequest",
683            supports_goto_targets_request,
684        );
685        let supports_step_in_targets_request = utils::attribute_bool_optional(
686            "supportsStepInTargetsRequest",
687            supports_step_in_targets_request,
688        );
689        let supports_completions_request = utils::attribute_bool_optional(
690            "supportsCompletionsRequest",
691            supports_completions_request,
692        );
693        let completion_trigger_characters = utils::attribute_array_optional(
694            "completionTriggerCharacters",
695            completion_trigger_characters,
696        );
697        let supports_modules_request =
698            utils::attribute_bool_optional("supportsModulesRequest", supports_modules_request);
699        let additional_module_columns =
700            utils::attribute_array_optional("additionalModuleColumns", additional_module_columns);
701        let supported_checksum_algorithms = utils::attribute_array_optional(
702            "supportedChecksumAlgorithms",
703            supported_checksum_algorithms,
704        );
705        let supports_restart_request =
706            utils::attribute_bool_optional("supportsRestartRequest", supports_restart_request);
707        let supports_exception_options =
708            utils::attribute_bool_optional("supportsExceptionOptions", supports_exception_options);
709        let supports_value_formatting_options = utils::attribute_bool_optional(
710            "supportsValueFormattingOptions",
711            supports_value_formatting_options,
712        );
713        let supports_exception_info_request = utils::attribute_bool_optional(
714            "supportsExceptionInfoRequest",
715            supports_exception_info_request,
716        );
717        let support_terminate_debuggee =
718            utils::attribute_bool_optional("supportTerminateDebuggee", support_terminate_debuggee);
719        let support_suspend_debuggee =
720            utils::attribute_bool_optional("supportSuspendDebuggee", support_suspend_debuggee);
721        let supports_delayed_stack_trace_loading = utils::attribute_bool_optional(
722            "supportsDelayedStackTraceLoading",
723            supports_delayed_stack_trace_loading,
724        );
725        let supports_loaded_sources_request = utils::attribute_bool_optional(
726            "supportsLoadedSourcesRequest",
727            supports_loaded_sources_request,
728        );
729        let supports_log_points =
730            utils::attribute_bool_optional("supportsLogPoints", supports_log_points);
731        let supports_terminate_threads_request = utils::attribute_bool_optional(
732            "supportsTerminateThreadsRequest",
733            supports_terminate_threads_request,
734        );
735        let supports_set_expression =
736            utils::attribute_bool_optional("supportsSetExpression", supports_set_expression);
737        let supports_terminate_request =
738            utils::attribute_bool_optional("supportsTerminateRequest", supports_terminate_request);
739        let supports_data_breakpoints =
740            utils::attribute_bool_optional("supportsDataBreakpoints", supports_data_breakpoints);
741        let supports_read_memory_request = utils::attribute_bool_optional(
742            "supportsReadMemoryRequest",
743            supports_read_memory_request,
744        );
745        let supports_write_memory_request = utils::attribute_bool_optional(
746            "supportsWriteMemoryRequest",
747            supports_write_memory_request,
748        );
749        let supports_disassemble_request = utils::attribute_bool_optional(
750            "supportsDisassembleRequest",
751            supports_disassemble_request,
752        );
753        let supports_cancel_request =
754            utils::attribute_bool_optional("supportsCancelRequest", supports_cancel_request);
755        let supports_breakpoint_locations_request = utils::attribute_bool_optional(
756            "supportsBreakpointLocationsRequest",
757            supports_breakpoint_locations_request,
758        );
759        let supports_clipboard_context =
760            utils::attribute_bool_optional("supportsClipboardContext", supports_clipboard_context);
761        let supports_stepping_granularity = utils::attribute_bool_optional(
762            "supportsSteppingGranularity",
763            supports_stepping_granularity,
764        );
765        let supports_instruction_breakpoints = utils::attribute_bool_optional(
766            "supportsInstructionBreakpoints",
767            supports_instruction_breakpoints,
768        );
769        let supports_exception_filter_options = utils::attribute_bool_optional(
770            "supportsExceptionFilterOptions",
771            supports_exception_filter_options,
772        );
773        let supports_single_thread_execution_requests = utils::attribute_bool_optional(
774            "supportsSingleThreadExecutionRequests",
775            supports_single_thread_execution_requests,
776        );
777
778        utils::finalize_object(
779            supports_configuration_done_request
780                .chain(supports_function_breakpoints)
781                .chain(supports_conditional_breakpoints)
782                .chain(supports_hit_conditional_breakpoints)
783                .chain(supports_evaluate_for_hovers)
784                .chain(exception_breakpoint_filters)
785                .chain(supports_step_back)
786                .chain(supports_set_variable)
787                .chain(supports_restart_frame)
788                .chain(supports_goto_targets_request)
789                .chain(supports_step_in_targets_request)
790                .chain(supports_completions_request)
791                .chain(completion_trigger_characters)
792                .chain(supports_modules_request)
793                .chain(additional_module_columns)
794                .chain(supported_checksum_algorithms)
795                .chain(supports_restart_request)
796                .chain(supports_exception_options)
797                .chain(supports_value_formatting_options)
798                .chain(supports_exception_info_request)
799                .chain(support_terminate_debuggee)
800                .chain(support_suspend_debuggee)
801                .chain(supports_delayed_stack_trace_loading)
802                .chain(supports_loaded_sources_request)
803                .chain(supports_log_points)
804                .chain(supports_terminate_threads_request)
805                .chain(supports_set_expression)
806                .chain(supports_terminate_request)
807                .chain(supports_data_breakpoints)
808                .chain(supports_read_memory_request)
809                .chain(supports_write_memory_request)
810                .chain(supports_disassemble_request)
811                .chain(supports_cancel_request)
812                .chain(supports_breakpoint_locations_request)
813                .chain(supports_clipboard_context)
814                .chain(supports_stepping_granularity)
815                .chain(supports_instruction_breakpoints)
816                .chain(supports_exception_filter_options)
817                .chain(supports_single_thread_execution_requests),
818        )
819    }
820}
821
822impl TryFrom<&Map<String, Value>> for Capabilities {
823    type Error = Error;
824
825    fn try_from(map: &Map<String, Value>) -> Result<Self, Self::Error> {
826        let supports_configuration_done_request =
827            utils::get_bool_optional(map, "supportsConfigurationDoneRequest")?;
828        let supports_function_breakpoints =
829            utils::get_bool_optional(map, "supportsFunctionBreakpoints")?;
830        let supports_conditional_breakpoints =
831            utils::get_bool_optional(map, "supportsConditionalBreakpoints")?;
832        let supports_hit_conditional_breakpoints =
833            utils::get_bool_optional(map, "supportsHitConditionalBreakpoints")?;
834        let supports_evaluate_for_hovers =
835            utils::get_bool_optional(map, "supportsEvaluateForHovers")?;
836        let exception_breakpoint_filters =
837            utils::get_array_optional(map, "exceptionBreakpointFilters")?;
838        let supports_step_back = utils::get_bool_optional(map, "supportsStepBack")?;
839        let supports_set_variable = utils::get_bool_optional(map, "supportsSetVariable")?;
840        let supports_restart_frame = utils::get_bool_optional(map, "supportsRestartFrame")?;
841        let supports_goto_targets_request =
842            utils::get_bool_optional(map, "supportsGotoTargetsRequest")?;
843        let supports_step_in_targets_request =
844            utils::get_bool_optional(map, "supportsStepInTargetsRequest")?;
845        let supports_completions_request =
846            utils::get_bool_optional(map, "supportsCompletionsRequest")?;
847        let completion_trigger_characters =
848            utils::get_array_of_string_optional(map, "completionTriggerCharacters")?;
849        let supports_modules_request = utils::get_bool_optional(map, "supportsModulesRequest")?;
850        let additional_module_columns = utils::get_array_optional(map, "additionalModuleColumns")?;
851        let supported_checksum_algorithms =
852            utils::get_array_of_string_enum_optional(map, "supportedChecksumAlgorithms")?;
853        let supports_restart_request = utils::get_bool_optional(map, "supportsRestartRequest")?;
854        let supports_exception_options = utils::get_bool_optional(map, "supportsExceptionOptions")?;
855        let supports_value_formatting_options =
856            utils::get_bool_optional(map, "supportsValueFormattingOptions")?;
857        let supports_exception_info_request =
858            utils::get_bool_optional(map, "supportsExceptionInfoRequest")?;
859        let support_terminate_debuggee = utils::get_bool_optional(map, "supportTerminateDebuggee")?;
860        let support_suspend_debuggee = utils::get_bool_optional(map, "supportSuspendDebuggee")?;
861        let supports_delayed_stack_trace_loading =
862            utils::get_bool_optional(map, "supportsDelayedStackTraceLoading")?;
863        let supports_loaded_sources_request =
864            utils::get_bool_optional(map, "supportsLoadedSourcesRequest")?;
865        let supports_log_points = utils::get_bool_optional(map, "supportsLogPoints")?;
866        let supports_terminate_threads_request =
867            utils::get_bool_optional(map, "supportsTerminateThreadsRequest")?;
868        let supports_set_expression = utils::get_bool_optional(map, "supportsSetExpression")?;
869        let supports_terminate_request = utils::get_bool_optional(map, "supportsTerminateRequest")?;
870        let supports_data_breakpoints = utils::get_bool_optional(map, "supportsDataBreakpoints")?;
871        let supports_read_memory_request =
872            utils::get_bool_optional(map, "supportsReadMemoryRequest")?;
873        let supports_write_memory_request =
874            utils::get_bool_optional(map, "supportsWriteMemoryRequest")?;
875        let supports_disassemble_request =
876            utils::get_bool_optional(map, "supportsDisassembleRequest")?;
877        let supports_cancel_request = utils::get_bool_optional(map, "supportsCancelRequest")?;
878        let supports_breakpoint_locations_request =
879            utils::get_bool_optional(map, "supportsBreakpointLocationsRequest")?;
880        let supports_clipboard_context = utils::get_bool_optional(map, "supportsClipboardContext")?;
881        let supports_stepping_granularity =
882            utils::get_bool_optional(map, "supportsSteppingGranularity")?;
883        let supports_instruction_breakpoints =
884            utils::get_bool_optional(map, "supportsInstructionBreakpoints")?;
885        let supports_exception_filter_options =
886            utils::get_bool_optional(map, "supportsExceptionFilterOptions")?;
887        let supports_single_thread_execution_requests =
888            utils::get_bool_optional(map, "supportsSingleThreadExecutionRequests")?;
889
890        Ok(Self {
891            supports_configuration_done_request,
892            supports_function_breakpoints,
893            supports_conditional_breakpoints,
894            supports_hit_conditional_breakpoints,
895            supports_evaluate_for_hovers,
896            exception_breakpoint_filters,
897            supports_step_back,
898            supports_set_variable,
899            supports_restart_frame,
900            supports_goto_targets_request,
901            supports_step_in_targets_request,
902            supports_completions_request,
903            completion_trigger_characters,
904            supports_modules_request,
905            additional_module_columns,
906            supported_checksum_algorithms,
907            supports_restart_request,
908            supports_exception_options,
909            supports_value_formatting_options,
910            supports_exception_info_request,
911            support_terminate_debuggee,
912            support_suspend_debuggee,
913            supports_delayed_stack_trace_loading,
914            supports_loaded_sources_request,
915            supports_log_points,
916            supports_terminate_threads_request,
917            supports_set_expression,
918            supports_terminate_request,
919            supports_data_breakpoints,
920            supports_read_memory_request,
921            supports_write_memory_request,
922            supports_disassemble_request,
923            supports_cancel_request,
924            supports_breakpoint_locations_request,
925            supports_clipboard_context,
926            supports_stepping_granularity,
927            supports_instruction_breakpoints,
928            supports_exception_filter_options,
929            supports_single_thread_execution_requests,
930        })
931    }
932}
933impl From<StackFrameModuleId> for Value {
934    fn from(id: StackFrameModuleId) -> Self {
935        match id {
936            StackFrameModuleId::Number(n) => n.into(),
937            StackFrameModuleId::String(s) => s.into(),
938        }
939    }
940}
941
942impl StackFrameModuleId {
943    pub fn try_from_map_optional(map: &Map<String, Value>) -> Result<Option<Self>, Error> {
944        map.get("moduleId")
945            .map(|id| match id {
946                Value::Number(n) => n
947                    .as_u64()
948                    .ok_or_else(|| Error::new("moduleId", Cause::MustBeUnsignedInteger))
949                    .map(Self::Number),
950                Value::String(s) => Ok(Self::String(s.clone())),
951                _ => Err(Error::new("moduleId", Cause::ExpectsEnum)),
952            })
953            .transpose()
954    }
955}
956
957impl From<StackFramePresentationHint> for &'static str {
958    fn from(hint: StackFramePresentationHint) -> Self {
959        match hint {
960            StackFramePresentationHint::Normal => "normal",
961            StackFramePresentationHint::Label => "label",
962            StackFramePresentationHint::Subtle => "subtle",
963        }
964    }
965}
966
967impl From<StackFramePresentationHint> for String {
968    fn from(hint: StackFramePresentationHint) -> Self {
969        <&'static str>::from(hint).into()
970    }
971}
972
973impl TryFrom<&str> for StackFramePresentationHint {
974    type Error = Error;
975
976    fn try_from(s: &str) -> Result<Self, Self::Error> {
977        match s {
978            "normal" => Ok(StackFramePresentationHint::Normal),
979            "label" => Ok(StackFramePresentationHint::Label),
980            "subtle" => Ok(StackFramePresentationHint::Subtle),
981            _ => Err(Error::new("presentationHint", Cause::ExpectsEnum)),
982        }
983    }
984}
985
986impl From<StackFrame> for Value {
987    fn from(frame: StackFrame) -> Self {
988        let StackFrame {
989            id,
990            name,
991            source,
992            line,
993            column,
994            end_line,
995            end_column,
996            can_restart,
997            instruction_pointer_reference,
998            module_id,
999            presentation_hint,
1000        } = frame;
1001
1002        let id = utils::attribute_u64("id", id);
1003        let name = utils::attribute_string("name", name);
1004        let source = utils::attribute_optional("source", source);
1005        let line = utils::attribute_u64("line", line);
1006        let column = utils::attribute_u64("column", column);
1007        let end_line = utils::attribute_u64_optional("endLine", end_line);
1008        let end_column = utils::attribute_u64_optional("endColumn", end_column);
1009        let can_restart = utils::attribute_bool_optional("canRestart", can_restart);
1010        let instruction_pointer_reference = utils::attribute_string_optional(
1011            "instructionPointerReference",
1012            instruction_pointer_reference,
1013        );
1014        let module_id = utils::attribute_optional("moduleId", module_id);
1015        let presentation_hint =
1016            utils::attribute_string_optional("presentationHint", presentation_hint);
1017
1018        utils::finalize_object(
1019            id.chain(name)
1020                .chain(source)
1021                .chain(line)
1022                .chain(column)
1023                .chain(end_line)
1024                .chain(end_column)
1025                .chain(can_restart)
1026                .chain(instruction_pointer_reference)
1027                .chain(module_id)
1028                .chain(presentation_hint),
1029        )
1030    }
1031}
1032
1033impl TryFrom<&Map<String, Value>> for StackFrame {
1034    type Error = Error;
1035
1036    fn try_from(map: &Map<String, Value>) -> Result<Self, Self::Error> {
1037        let id = utils::get_u64(map, "id")?;
1038        let name = utils::get_string(map, "name")?;
1039        let source = utils::get_object_optional(map, "source")?;
1040        let line = utils::get_u64(map, "line")?;
1041        let column = utils::get_u64(map, "column")?;
1042        let end_line = utils::get_u64_optional(map, "endLine")?;
1043        let end_column = utils::get_u64_optional(map, "endColumn")?;
1044        let can_restart = utils::get_bool_optional(map, "canRestart")?;
1045        let instruction_pointer_reference =
1046            utils::get_string_optional(map, "instructionPointerReference")?;
1047        let module_id = StackFrameModuleId::try_from_map_optional(map)?;
1048        let presentation_hint = utils::get_str_optional(map, "presentationHint")?
1049            .map(StackFramePresentationHint::try_from)
1050            .transpose()?;
1051
1052        Ok(Self {
1053            id,
1054            name,
1055            source,
1056            line,
1057            column,
1058            end_line,
1059            end_column,
1060            can_restart,
1061            instruction_pointer_reference,
1062            module_id,
1063            presentation_hint,
1064        })
1065    }
1066}
1067
1068impl From<StackFrameFormat> for Value {
1069    fn from(format: StackFrameFormat) -> Self {
1070        let StackFrameFormat {
1071            parameters,
1072            parameter_types,
1073            parameter_names,
1074            parameter_values,
1075            line,
1076            module,
1077            include_all,
1078        } = format;
1079
1080        let parameters = utils::attribute_bool_optional("parameters", parameters);
1081        let parameter_types = utils::attribute_bool_optional("parameterTypes", parameter_types);
1082        let parameter_names = utils::attribute_bool_optional("parameterNames", parameter_names);
1083        let parameter_values = utils::attribute_bool_optional("parameterValues", parameter_values);
1084        let line = utils::attribute_bool_optional("line", line);
1085        let module = utils::attribute_bool_optional("module", module);
1086        let include_all = utils::attribute_bool_optional("includeAll", include_all);
1087
1088        utils::finalize_object(
1089            parameters
1090                .chain(parameter_types)
1091                .chain(parameter_names)
1092                .chain(parameter_values)
1093                .chain(line)
1094                .chain(module)
1095                .chain(include_all),
1096        )
1097    }
1098}
1099
1100impl TryFrom<&Map<String, Value>> for StackFrameFormat {
1101    type Error = Error;
1102
1103    fn try_from(map: &Map<String, Value>) -> Result<Self, Self::Error> {
1104        let parameters = utils::get_bool_optional(map, "parameters")?;
1105        let parameter_types = utils::get_bool_optional(map, "parameterTypes")?;
1106        let parameter_names = utils::get_bool_optional(map, "parameterNames")?;
1107        let parameter_values = utils::get_bool_optional(map, "parameterValues")?;
1108        let line = utils::get_bool_optional(map, "line")?;
1109        let module = utils::get_bool_optional(map, "module")?;
1110        let include_all = utils::get_bool_optional(map, "includeAll")?;
1111
1112        Ok(Self {
1113            parameters,
1114            parameter_types,
1115            parameter_names,
1116            parameter_values,
1117            line,
1118            module,
1119            include_all,
1120        })
1121    }
1122}
1123
1124impl From<ValueFormat> for Value {
1125    fn from(format: ValueFormat) -> Self {
1126        let ValueFormat { hex } = format;
1127
1128        let hex = utils::attribute_bool_optional("hex", hex);
1129
1130        utils::finalize_object(hex)
1131    }
1132}
1133
1134impl TryFrom<&Map<String, Value>> for ValueFormat {
1135    type Error = Error;
1136
1137    fn try_from(map: &Map<String, Value>) -> Result<Self, Self::Error> {
1138        let hex = utils::get_bool_optional(map, "hex")?;
1139
1140        Ok(Self { hex })
1141    }
1142}