Skip to main content

flowrlib/
debug_command.rs

1use std::fmt;
2
3use serde_derive::{Deserialize, Serialize};
4
5/// Types of `Params` used in communications between the debugger and the `debug_client`
6#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
7pub enum BreakpointSpec {
8    /// All existing breakpoints
9    All,
10    /// A positive integer was specified - could be a function or a job number
11    Numeric(usize),
12    /// A descriptor for the `Output` of a `Function` was specified
13    Output((usize, String)),
14    /// A descriptor for the `Inout` of a `Function` was specified
15    Input((usize, usize)),
16    /// A description of a "block" (when one function is blocked from running by another) was specified
17    Block((Option<usize>, Option<usize>)),
18}
19
20/// A Command sent by the `debug_client` to the debugger
21#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
22pub enum DebugCommand {
23    /// Acknowledge event processed correctly
24    Ack,
25    /// Set a `breakpoint` - with an optional parameter
26    Breakpoint(Option<BreakpointSpec>),
27    /// `continue` execution of the flow
28    Continue,
29    /// Debug client is starting
30    DebugClientStarting,
31    /// `delete` an existing breakpoint - with an optional parameter
32    Delete(Option<BreakpointSpec>),
33    /// An error on the client side
34    Error(String),
35    /// `exit` the debugger and runtime
36    ExitDebugger,
37    /// List of all functions
38    FunctionList,
39    /// `inspect` a function
40    InspectFunction(usize),
41    /// Inspect overall state
42    Inspect,
43    /// Inspect an Input (`function_id`, `input_number`)
44    InspectInput(usize, usize),
45    /// Inspect an Output (`function_id`, `sub_path`)
46    InspectOutput(usize, String),
47    /// Inspect a Block (optional source `function_id`, optional `destination_function_id`)
48    InspectBlock(Option<usize>, Option<usize>),
49    /// Invalid - used when deserialization goes wrong
50    Invalid,
51    /// `list` existing breakpoints
52    List,
53    /// `modify` a debugger or runtime state value e.g. jobs=1 to set parallel jobs to 1
54    Modify(Option<Vec<String>>),
55    /// `reset` flow execution back to the initial state, or run the flow from the start
56    RunReset,
57    /// `step` forward in flow execution by executing one (default) or more `Jobs`
58    Step(Option<usize>),
59    /// `validate` the current state
60    Validate,
61}
62
63impl fmt::Display for DebugCommand {
64    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65        write!(f, "DebugCommand {}", String::from(self))
66    }
67}
68
69impl From<&DebugCommand> for String {
70    fn from(command: &DebugCommand) -> Self {
71        serde_json::to_string(command).unwrap_or_default()
72    }
73}
74
75impl From<DebugCommand> for String {
76    fn from(command: DebugCommand) -> Self {
77        serde_json::to_string(&command).unwrap_or_default()
78    }
79}
80
81impl From<String> for DebugCommand {
82    fn from(command_string: String) -> Self {
83        match serde_json::from_str(&command_string) {
84            Ok(command) => command,
85            _ => DebugCommand::Invalid,
86        }
87    }
88}
89
90#[cfg(test)]
91#[allow(clippy::unwrap_used, clippy::expect_used)]
92mod test {
93    use crate::debug_command::DebugCommand;
94
95    #[test]
96    fn display_debug_command() {
97        println!("{}", DebugCommand::Ack);
98        println!("{}", DebugCommand::Breakpoint(None));
99        println!("{}", DebugCommand::Continue);
100        println!("{}", DebugCommand::Delete(None));
101        println!("{}", DebugCommand::Error("Hello".into()));
102        println!("{}", DebugCommand::ExitDebugger);
103        println!("{}", DebugCommand::FunctionList);
104        println!("{}", DebugCommand::InspectFunction(0));
105        println!("{}", DebugCommand::Inspect);
106        println!("{}", DebugCommand::InspectInput(0, 0));
107        println!("{}", DebugCommand::InspectOutput(0, "Hello".into()));
108        println!("{}", DebugCommand::InspectBlock(None, None));
109        println!("{}", DebugCommand::Invalid);
110        println!("{}", DebugCommand::List);
111        println!("{}", DebugCommand::RunReset);
112        println!("{}", DebugCommand::Step(None));
113        println!("{}", DebugCommand::Validate);
114        println!("{}", DebugCommand::DebugClientStarting);
115        println!("{}", DebugCommand::Modify(None));
116    }
117
118    #[test]
119    fn test_command_to_string() {
120        assert_eq!(String::from(DebugCommand::Ack), "\"Ack\"".to_string());
121    }
122
123    #[test]
124    fn debug_command_from_string() {
125        let command: DebugCommand = DebugCommand::from("\"Ack\"".to_string());
126        assert_eq!(command, DebugCommand::Ack);
127    }
128
129    #[test]
130    fn invalid_debug_command_from_string() {
131        let command: DebugCommand = DebugCommand::from("\"Foo\"".to_string());
132        assert_eq!(command, DebugCommand::Invalid);
133    }
134}