use serde::{Deserialize, Serialize};
use crate::{ControlModeResponse, HandshakeResponse, LayoutName, RmuxError, SdkWaitId};
#[path = "response/session.rs"]
mod session;
pub use session::{
HasSessionResponse, KillSessionResponse, ListSessionsResponse, NewSessionResponse,
RenameSessionResponse,
};
#[path = "response/server.rs"]
mod server;
pub use server::{
KillServerResponse, LockClientResponse, LockServerResponse, LockSessionResponse,
ServerAccessResponse,
};
#[path = "response/target.rs"]
mod target;
pub use target::ResolveTargetResponse;
#[path = "response/window.rs"]
mod window;
pub use window::{
KillWindowResponse, LastWindowResponse, LinkWindowResponse, ListWindowsResponse,
MoveWindowResponse, NewWindowResponse, NextWindowResponse, PreviousWindowResponse,
RenameWindowResponse, ResizeWindowResponse, RespawnWindowResponse, RotateWindowResponse,
SelectWindowResponse, SwapWindowResponse, UnlinkWindowResponse, WindowListEntry,
};
#[path = "response/pane.rs"]
mod pane;
pub use pane::{
BreakPaneResponse, DisplayPanesResponse, JoinPaneResponse, KillPaneResponse, LastPaneResponse,
ListPanesResponse, MovePaneResponse, PaneOutputCursor, PaneOutputCursorResponse,
PaneOutputEvent, PaneOutputLagNotice, PaneOutputLagResponse, PaneRecentOutput,
PaneSnapshotCell, PaneSnapshotCursor, PaneSnapshotResponse, PipePaneResponse,
ResizePaneResponse, RespawnPaneResponse, SelectPaneResponse, SendKeysResponse,
SplitWindowResponse, SubscribePaneOutputResponse, SwapPaneResponse,
UnsubscribePaneOutputResponse,
};
#[path = "response/client.rs"]
mod client;
pub use client::{
AttachSessionResponse, DetachClientResponse, ListClientsResponse, RefreshClientResponse,
SuspendClientResponse, SwitchClientResponse,
};
#[path = "response/keys.rs"]
mod keys;
pub use keys::{
BindKeyResponse, ClockModeResponse, CopyModeResponse, ListKeysResponse, SendPrefixResponse,
UnbindKeyResponse,
};
#[path = "response/options.rs"]
mod options;
pub use options::{
SetEnvironmentResponse, SetHookResponse, SetOptionByNameResponse, SetOptionResponse,
ShowEnvironmentResponse, ShowHooksResponse, ShowOptionsResponse,
};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Response {
NewSession(NewSessionResponse),
HasSession(HasSessionResponse),
KillSession(KillSessionResponse),
NewWindow(NewWindowResponse),
KillWindow(KillWindowResponse),
SelectWindow(SelectWindowResponse),
RenameWindow(RenameWindowResponse),
NextWindow(NextWindowResponse),
PreviousWindow(PreviousWindowResponse),
LastWindow(LastWindowResponse),
ListWindows(ListWindowsResponse),
MoveWindow(MoveWindowResponse),
SwapWindow(SwapWindowResponse),
RotateWindow(RotateWindowResponse),
SplitWindow(SplitWindowResponse),
SwapPane(SwapPaneResponse),
LastPane(LastPaneResponse),
JoinPane(JoinPaneResponse),
BreakPane(BreakPaneResponse),
KillPane(KillPaneResponse),
SelectLayout(SelectLayoutResponse),
ResizePane(ResizePaneResponse),
DisplayPanes(DisplayPanesResponse),
SelectPane(SelectPaneResponse),
SendKeys(SendKeysResponse),
AttachSession(AttachSessionResponse),
SwitchClient(SwitchClientResponse),
DetachClient(DetachClientResponse),
SetOption(SetOptionResponse),
SetEnvironment(SetEnvironmentResponse),
SetHook(SetHookResponse),
Error(ErrorResponse),
NextLayout(NextLayoutResponse),
PreviousLayout(PreviousLayoutResponse),
ShowOptions(ShowOptionsResponse),
ShowEnvironment(ShowEnvironmentResponse),
SetBuffer(SetBufferResponse),
ShowBuffer(ShowBufferResponse),
PasteBuffer(PasteBufferResponse),
ListBuffers(ListBuffersResponse),
DeleteBuffer(DeleteBufferResponse),
LoadBuffer(LoadBufferResponse),
SaveBuffer(SaveBufferResponse),
CapturePane(CapturePaneResponse),
DisplayMessage(DisplayMessageResponse),
RunShell(RunShellResponse),
IfShell(IfShellResponse),
WaitFor(WaitForResponse),
RenameSession(RenameSessionResponse),
ListSessions(ListSessionsResponse),
ListPanes(ListPanesResponse),
SourceFile(SourceFileResponse),
SetOptionByName(SetOptionByNameResponse),
ShowHooks(ShowHooksResponse),
BindKey(BindKeyResponse),
UnbindKey(UnbindKeyResponse),
ListKeys(ListKeysResponse),
SendPrefix(SendPrefixResponse),
ClearHistory(ClearHistoryResponse),
CopyMode(CopyModeResponse),
ControlMode(ControlModeResponse),
ClockMode(ClockModeResponse),
ShowMessages(ShowMessagesResponse),
KillServer(KillServerResponse),
LockServer(LockServerResponse),
LockSession(LockSessionResponse),
LockClient(LockClientResponse),
ServerAccess(ServerAccessResponse),
RefreshClient(RefreshClientResponse),
ListClients(ListClientsResponse),
SuspendClient(SuspendClientResponse),
ResizeWindow(ResizeWindowResponse),
RespawnWindow(RespawnWindowResponse),
MovePane(MovePaneResponse),
PipePane(PipePaneResponse),
RespawnPane(RespawnPaneResponse),
LinkWindow(LinkWindowResponse),
UnlinkWindow(UnlinkWindowResponse),
ResolveTarget(ResolveTargetResponse),
Handshake(HandshakeResponse),
PaneSnapshot(PaneSnapshotResponse),
SubscribePaneOutput(SubscribePaneOutputResponse),
UnsubscribePaneOutput(UnsubscribePaneOutputResponse),
PaneOutputCursor(PaneOutputCursorResponse),
PaneOutputLag(PaneOutputLagResponse),
SdkWaitForOutput(SdkWaitForOutputResponse),
CancelSdkWait(CancelSdkWaitResponse),
}
impl Response {
#[must_use]
pub const fn command_name(&self) -> &'static str {
match self {
Self::NewSession(_) => "new-session",
Self::HasSession(_) => "has-session",
Self::KillSession(_) => "kill-session",
Self::NewWindow(_) => "new-window",
Self::KillWindow(_) => "kill-window",
Self::SelectWindow(_) => "select-window",
Self::RenameWindow(_) => "rename-window",
Self::NextWindow(_) => "next-window",
Self::PreviousWindow(_) => "previous-window",
Self::LastWindow(_) => "last-window",
Self::ListWindows(_) => "list-windows",
Self::MoveWindow(_) => "move-window",
Self::SwapWindow(_) => "swap-window",
Self::RotateWindow(_) => "rotate-window",
Self::SplitWindow(_) => "split-window",
Self::SwapPane(_) => "swap-pane",
Self::LastPane(_) => "last-pane",
Self::JoinPane(_) => "join-pane",
Self::BreakPane(_) => "break-pane",
Self::KillPane(_) => "kill-pane",
Self::SelectLayout(_) => "select-layout",
Self::ResizePane(_) => "resize-pane",
Self::DisplayPanes(_) => "display-panes",
Self::SelectPane(_) => "select-pane",
Self::SendKeys(_) => "send-keys",
Self::AttachSession(_) => "attach-session",
Self::SwitchClient(_) => "switch-client",
Self::DetachClient(_) => "detach-client",
Self::SetOption(_) | Self::SetOptionByName(_) => "set-option",
Self::SetEnvironment(_) => "set-environment",
Self::SetHook(_) => "set-hook",
Self::Error(_) => "error",
Self::NextLayout(_) => "next-layout",
Self::PreviousLayout(_) => "previous-layout",
Self::ShowOptions(_) => "show-options",
Self::ShowEnvironment(_) => "show-environment",
Self::SetBuffer(_) => "set-buffer",
Self::ShowBuffer(_) => "show-buffer",
Self::PasteBuffer(_) => "paste-buffer",
Self::ListBuffers(_) => "list-buffers",
Self::DeleteBuffer(_) => "delete-buffer",
Self::LoadBuffer(_) => "load-buffer",
Self::SaveBuffer(_) => "save-buffer",
Self::CapturePane(_) => "capture-pane",
Self::DisplayMessage(_) => "display-message",
Self::RunShell(_) => "run-shell",
Self::IfShell(_) => "if-shell",
Self::WaitFor(_) => "wait-for",
Self::RenameSession(_) => "rename-session",
Self::ListSessions(_) => "list-sessions",
Self::ListPanes(_) => "list-panes",
Self::SourceFile(_) => "source-file",
Self::ShowHooks(_) => "show-hooks",
Self::BindKey(_) => "bind-key",
Self::UnbindKey(_) => "unbind-key",
Self::ListKeys(_) => "list-keys",
Self::SendPrefix(_) => "send-prefix",
Self::ClearHistory(_) => "clear-history",
Self::CopyMode(_) => "copy-mode",
Self::ControlMode(_) => "control-mode",
Self::ClockMode(_) => "clock-mode",
Self::ShowMessages(_) => "show-messages",
Self::KillServer(_) => "kill-server",
Self::LockServer(_) => "lock-server",
Self::LockSession(_) => "lock-session",
Self::LockClient(_) => "lock-client",
Self::ServerAccess(_) => "server-access",
Self::RefreshClient(_) => "refresh-client",
Self::ListClients(_) => "list-clients",
Self::SuspendClient(_) => "suspend-client",
Self::ResizeWindow(_) => "resize-window",
Self::RespawnWindow(_) => "respawn-window",
Self::MovePane(_) => "move-pane",
Self::PipePane(_) => "pipe-pane",
Self::RespawnPane(_) => "respawn-pane",
Self::PaneSnapshot(_) => "pane-snapshot",
Self::SubscribePaneOutput(_) => "subscribe-pane-output",
Self::UnsubscribePaneOutput(_) => "unsubscribe-pane-output",
Self::PaneOutputCursor(_) => "pane-output-cursor",
Self::PaneOutputLag(_) => "pane-output-lag",
Self::SdkWaitForOutput(_) => "sdk-wait-output",
Self::CancelSdkWait(_) => "cancel-sdk-wait",
Self::LinkWindow(_) => "link-window",
Self::UnlinkWindow(_) => "unlink-window",
Self::ResolveTarget(_) => "resolve-target",
Self::Handshake(_) => "handshake",
}
}
#[must_use]
pub const fn is_error(&self) -> bool {
matches!(self, Self::Error(_))
}
#[must_use]
pub fn command_output(&self) -> Option<&CommandOutput> {
match self {
Self::NewSession(response) => response.command_output(),
Self::ListWindows(response) => Some(response.command_output()),
Self::ShowOptions(response) => Some(response.command_output()),
Self::ShowEnvironment(response) => Some(response.command_output()),
Self::ShowHooks(response) => Some(response.command_output()),
Self::ShowBuffer(response) => Some(response.command_output()),
Self::ListBuffers(response) => Some(response.command_output()),
Self::CapturePane(response) => response.command_output(),
Self::DisplayMessage(response) => response.command_output(),
Self::ResolveTarget(_) => None,
Self::RunShell(response) => response.command_output(),
Self::IfShell(response) => response.command_output(),
Self::ListSessions(response) => Some(response.command_output()),
Self::ListPanes(response) => Some(response.command_output()),
Self::SourceFile(response) => response.command_output(),
Self::SetOptionByName(_) => None,
Self::ListKeys(response) => Some(response.command_output()),
Self::ControlMode(_) => None,
Self::ClockMode(_) => None,
Self::ShowMessages(response) => Some(response.command_output()),
Self::ServerAccess(response) => Some(response.command_output()),
Self::ListClients(response) => Some(response.command_output()),
Self::BreakPane(response) => response.command_output(),
Self::Handshake(_) => None,
Self::SubscribePaneOutput(_)
| Self::UnsubscribePaneOutput(_)
| Self::PaneOutputCursor(_)
| Self::PaneOutputLag(_)
| Self::SdkWaitForOutput(_)
| Self::CancelSdkWait(_) => None,
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CommandOutput {
pub stdout: Vec<u8>,
}
impl CommandOutput {
#[must_use]
pub fn from_stdout(stdout: impl Into<Vec<u8>>) -> Self {
Self {
stdout: stdout.into(),
}
}
#[must_use]
pub fn stdout(&self) -> &[u8] {
&self.stdout
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct SelectLayoutResponse {
pub layout: LayoutName,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct NextLayoutResponse {
pub layout: LayoutName,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct PreviousLayoutResponse {
pub layout: LayoutName,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SetBufferResponse {
pub buffer_name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ShowBufferResponse {
pub output: CommandOutput,
}
impl ShowBufferResponse {
#[must_use]
pub fn command_output(&self) -> &CommandOutput {
&self.output
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PasteBufferResponse {
pub buffer_name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ListBuffersResponse {
pub output: CommandOutput,
}
impl ListBuffersResponse {
#[must_use]
pub fn command_output(&self) -> &CommandOutput {
&self.output
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DeleteBufferResponse {
pub buffer_name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LoadBufferResponse {
pub buffer_name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SaveBufferResponse {
pub buffer_name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CapturePaneResponse {
pub buffer_name: Option<String>,
pub output: Option<CommandOutput>,
}
impl CapturePaneResponse {
#[must_use]
pub fn from_buffer(buffer_name: String) -> Self {
Self {
buffer_name: Some(buffer_name),
output: None,
}
}
#[must_use]
pub fn from_output(output: CommandOutput) -> Self {
Self {
buffer_name: None,
output: Some(output),
}
}
#[must_use]
pub fn command_output(&self) -> Option<&CommandOutput> {
self.output.as_ref()
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClearHistoryResponse;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ShowMessagesResponse {
pub output: CommandOutput,
}
impl ShowMessagesResponse {
#[must_use]
pub const fn from_output(output: CommandOutput) -> Self {
Self { output }
}
#[must_use]
pub const fn command_output(&self) -> &CommandOutput {
&self.output
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DisplayMessageResponse {
pub output: Option<CommandOutput>,
}
impl DisplayMessageResponse {
#[must_use]
pub const fn no_output() -> Self {
Self { output: None }
}
#[must_use]
pub fn from_output(output: CommandOutput) -> Self {
Self {
output: Some(output),
}
}
#[must_use]
pub fn command_output(&self) -> Option<&CommandOutput> {
self.output.as_ref()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RunShellResponse {
pub output: Option<CommandOutput>,
}
impl RunShellResponse {
#[must_use]
pub const fn background() -> Self {
Self { output: None }
}
#[must_use]
pub const fn no_output() -> Self {
Self::background()
}
#[must_use]
pub fn from_output(output: CommandOutput) -> Self {
Self {
output: Some(output),
}
}
#[must_use]
pub fn command_output(&self) -> Option<&CommandOutput> {
self.output.as_ref()
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct IfShellResponse {
pub output: Option<CommandOutput>,
}
impl IfShellResponse {
#[must_use]
pub const fn no_output() -> Self {
Self { output: None }
}
#[must_use]
pub fn from_output(output: CommandOutput) -> Self {
Self {
output: Some(output),
}
}
#[must_use]
pub fn command_output(&self) -> Option<&CommandOutput> {
self.output.as_ref()
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct SourceFileResponse {
pub output: Option<CommandOutput>,
}
impl SourceFileResponse {
#[must_use]
pub const fn no_output() -> Self {
Self { output: None }
}
#[must_use]
pub fn from_output(output: CommandOutput) -> Self {
Self {
output: Some(output),
}
}
#[must_use]
pub fn command_output(&self) -> Option<&CommandOutput> {
self.output.as_ref()
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct WaitForResponse;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum SdkWaitOutcome {
Matched,
Cancelled,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct SdkWaitForOutputResponse {
pub wait_id: SdkWaitId,
pub outcome: SdkWaitOutcome,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct CancelSdkWaitResponse {
pub wait_id: SdkWaitId,
pub removed: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ErrorResponse {
pub error: RmuxError,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{OptionScopeSelector, SetOptionMode};
#[test]
fn response_command_names_cover_base_aliases_and_error_tag() {
assert_eq!(
Response::HasSession(HasSessionResponse { exists: true }).command_name(),
"has-session"
);
assert_eq!(
Response::SetOptionByName(SetOptionByNameResponse {
scope: OptionScopeSelector::ServerGlobal,
name: "status".to_owned(),
mode: SetOptionMode::Replace,
})
.command_name(),
"set-option"
);
assert_eq!(
Response::KillServer(KillServerResponse).command_name(),
"kill-server"
);
assert_eq!(
Response::Error(ErrorResponse {
error: RmuxError::Server("failed".to_owned()),
})
.command_name(),
"error"
);
assert_eq!(
Response::Handshake(HandshakeResponse::current()).command_name(),
"handshake"
);
assert_eq!(
Response::SdkWaitForOutput(SdkWaitForOutputResponse {
wait_id: SdkWaitId::new(1),
outcome: SdkWaitOutcome::Matched,
})
.command_name(),
"sdk-wait-output"
);
assert_eq!(
Response::CancelSdkWait(CancelSdkWaitResponse {
wait_id: SdkWaitId::new(1),
removed: false,
})
.command_name(),
"cancel-sdk-wait"
);
assert_eq!(
Response::WaitFor(WaitForResponse).command_name(),
"wait-for"
);
}
}