1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
mod batch;
mod capabilities;
mod custom;
mod forward;
mod internal_debug;
mod io;
mod sequence;
mod transform;

pub use batch::*;
pub use capabilities::*;
pub use custom::*;
pub use forward::*;
pub use internal_debug::*;
pub use io::*;
pub use sequence::*;
pub use transform::*;

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

// NOTE: Cannot adjacently tag as JsonSchema does not support it and
//       it leads to deserialization errors with enum variants without
//       any real arguments (empty struct doesn't fix)
#[derive(JsonSchema, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
// #[serde(tag = "type")]
#[serde(tag = "type", content = "payload")]
pub enum Request {
    // ------------------------------------------------------------------------
    // Heartbeats are used to ensure remote instances are alive
    #[serde(rename = "heartbeat_request")]
    #[allow(dead_code)]
    Heartbeat,

    // ------------------------------------------------------------------------
    // Version information to ensure that we don't have
    // conflicting functionality
    #[serde(rename = "version_request")]
    #[allow(dead_code)]
    Version,

    // ------------------------------------------------------------------------
    // Capability information to convey what is available remotely, which
    // can differ based on enabled features at compile time
    #[serde(rename = "capabilities_request")]
    #[allow(dead_code)]
    Capabilities,

    // ------------------------------------------------------------------------
    // Dir-based operations such as creating and listing entries
    /// This will be sent to indicate the desire to create a new directory
    #[serde(rename = "create_dir_request")]
    CreateDir(CreateDirArgs),

    /// This will be sent to indicate the desire to rename a directory
    #[serde(rename = "rename_dir_request")]
    RenameDir(RenameDirArgs),

    /// This will be sent to indicate the desire to remove a directory
    #[serde(rename = "remove_dir_request")]
    RemoveDir(RemoveDirArgs),

    /// This will be sent to indicate the desire to list all files/directories
    /// at the provided path
    #[serde(rename = "list_dir_contents_request")]
    ListDirContents(ListDirContentsArgs),

    // ------------------------------------------------------------------------
    // File-based operations such as reading and writing
    /// This will be sent to indicate the desire to read/write a file,
    /// and can also be used to retrieve an already-open file's id/sig
    #[serde(rename = "open_file_request")]
    OpenFile(OpenFileArgs),

    /// This will be sent to indicate the desire to close an open file
    #[serde(rename = "close_file_request")]
    CloseFile(CloseFileArgs),

    /// This will be sent to indicate the desire to rename a file
    #[serde(rename = "rename_unopened_file_request")]
    RenameUnopenedFile(RenameUnopenedFileArgs),

    /// This will be sent to indicate the desire to rename an open file
    #[serde(rename = "rename_file_request")]
    RenameFile(RenameFileArgs),

    /// This will be sent to indicate the desire to remove a file
    #[serde(rename = "remove_unopened_file_request")]
    RemoveUnopenedFile(RemoveUnopenedFileArgs),

    /// This will be sent to indicate the desire to remove an open file
    #[serde(rename = "remove_file_request")]
    RemoveFile(RemoveFileArgs),

    /// This will be sent to indicate the desire to read a file's contents
    #[serde(rename = "read_file_request")]
    ReadFile(ReadFileArgs),

    /// This will be sent to indicate the desire to write a file's contents
    #[serde(rename = "write_file_request")]
    WriteFile(WriteFileArgs),

    // ------------------------------------------------------------------------
    // Program execution operations such as running and streaming
    /// This will be sent to execute a remote proccess on the server
    #[serde(rename = "exec_proc_request")]
    ExecProc(ExecProcArgs),

    /// This will be sent to feed input to a remote process on the server, if
    /// enabled when first executing
    #[serde(rename = "write_proc_stdin_request")]
    WriteProcStdin(WriteProcStdinArgs),

    /// This will be sent to request all stdout for a remote process on
    /// the server since the last request was made
    #[serde(rename = "read_proc_stdout_request")]
    ReadProcStdout(ReadProcStdoutArgs),

    /// This will be sent to request all stderr for a remote process on
    /// the server since the last request was made
    #[serde(rename = "read_proc_stderr_request")]
    ReadProcStderr(ReadProcStderrArgs),

    /// This will be sent to kill a remote process on the server
    #[serde(rename = "kill_proc_request")]
    KillProc(KillProcArgs),

    /// This will be sent to request the status of a running process on
    /// the server
    #[serde(rename = "read_proc_status_request")]
    ReadProcStatus(ReadProcStatusArgs),

    // ------------------------------------------------------------------------
    // Miscellaneous, adhoc messages
    /// This will be sent to execute a collection of operations sequentially
    #[serde(rename = "sequence_request")]
    Sequence(SequenceArgs),

    /// This will be sent to execute a collection of operations in parallel
    #[serde(rename = "batch_request")]
    Batch(BatchArgs),

    /// This will be sent to either the client or server and the msg will be
    /// passed along to the associated address (if possible)
    #[serde(rename = "forward_request")]
    Forward(ForwardArgs),

    /// This will be sent in either direction to provide a custom content
    /// that would be evaluated through user-implemented handlers
    #[serde(rename = "custom_request")]
    Custom(CustomArgs),

    /// For debugging purposes when needing to query the state of client/server
    #[serde(rename = "internal_debug_request")]
    InternalDebug(InternalDebugArgs),
}

impl Request {
    /// Converts a request into a lazily transformed request using the
    /// provided rules as transformation specifications
    pub fn into_lazily_transformed(
        self,
        rules: Vec<TransformRule>,
    ) -> LazilyTransformedRequest {
        LazilyTransformedRequest::new(self, rules)
    }
}

impl crate::core::SchemaInfo for Request {}