Skip to main content

rmux_proto/request/
client.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{ClientTerminalContext, SessionName, TerminalSize};
4
5/// Request payload for `attach-session`.
6#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7pub struct AttachSessionRequest {
8    /// The exact target session name.
9    pub target: SessionName,
10}
11
12/// Extended request payload for `attach-session`.
13#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14pub struct AttachSessionExtRequest {
15    /// The optional exact target session name.
16    pub target: Option<SessionName>,
17    /// Whether other attached clients should be detached first.
18    #[serde(default)]
19    pub detach_other_clients: bool,
20    /// Whether other attached clients should be detached and terminated.
21    #[serde(default)]
22    pub kill_other_clients: bool,
23    /// Whether readonly attach mode should be enabled.
24    #[serde(default)]
25    pub read_only: bool,
26    /// Whether client environment updates should be skipped.
27    #[serde(default)]
28    pub skip_environment_update: bool,
29    /// Optional tmux client-flag names such as `read-only` or `active-pane`.
30    #[serde(default)]
31    pub flags: Option<Vec<String>>,
32}
33
34/// Further-extended request payload for `attach-session`.
35#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
36pub struct AttachSessionExt2Request {
37    /// The optional exact target session name.
38    #[serde(default)]
39    pub target: Option<SessionName>,
40    /// The optional raw tmux-style target text, including window/pane selectors.
41    #[serde(default)]
42    pub target_spec: Option<String>,
43    /// Whether other attached clients should be detached first.
44    #[serde(default)]
45    pub detach_other_clients: bool,
46    /// Whether other attached clients should be detached and terminated.
47    #[serde(default)]
48    pub kill_other_clients: bool,
49    /// Whether readonly attach mode should be enabled.
50    #[serde(default)]
51    pub read_only: bool,
52    /// Whether client environment updates should be skipped.
53    #[serde(default)]
54    pub skip_environment_update: bool,
55    /// Optional tmux client-flag names such as `read-only` or `active-pane`.
56    #[serde(default)]
57    pub flags: Option<Vec<String>>,
58    /// Optional tmux format-expanded working directory applied to the target session.
59    #[serde(default)]
60    pub working_directory: Option<String>,
61    /// Terminal/runtime hints captured from the invoking client.
62    #[serde(default)]
63    pub client_terminal: ClientTerminalContext,
64    /// The invoking client terminal size, when known.
65    #[serde(default)]
66    pub client_size: Option<TerminalSize>,
67}
68
69/// Attach request payload with explicit attach-stream client capabilities.
70#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
71pub struct AttachSessionExt3Request {
72    /// The optional exact target session name.
73    #[serde(default)]
74    pub target: Option<SessionName>,
75    /// The optional raw tmux-style target text, including window/pane selectors.
76    #[serde(default)]
77    pub target_spec: Option<String>,
78    /// Whether other attached clients should be detached first.
79    #[serde(default)]
80    pub detach_other_clients: bool,
81    /// Whether other attached clients should be detached and terminated.
82    #[serde(default)]
83    pub kill_other_clients: bool,
84    /// Whether readonly attach mode should be enabled.
85    #[serde(default)]
86    pub read_only: bool,
87    /// Whether client environment updates should be skipped.
88    #[serde(default)]
89    pub skip_environment_update: bool,
90    /// Optional tmux client-flag names such as `read-only` or `active-pane`.
91    #[serde(default)]
92    pub flags: Option<Vec<String>>,
93    /// Optional tmux format-expanded working directory applied to the target session.
94    #[serde(default)]
95    pub working_directory: Option<String>,
96    /// Terminal/runtime hints captured from the invoking client.
97    #[serde(default)]
98    pub client_terminal: ClientTerminalContext,
99    /// The invoking client terminal size, when known.
100    #[serde(default)]
101    pub client_size: Option<TerminalSize>,
102    /// Attach-stream messages this client can decode.
103    #[serde(default)]
104    pub attach_capabilities: Vec<String>,
105}
106
107impl AttachSessionExt3Request {
108    /// Builds the capability-aware request from the v2 attach request shape.
109    #[must_use]
110    pub fn from_ext2(request: AttachSessionExt2Request, attach_capabilities: Vec<String>) -> Self {
111        Self {
112            target: request.target,
113            target_spec: request.target_spec,
114            detach_other_clients: request.detach_other_clients,
115            kill_other_clients: request.kill_other_clients,
116            read_only: request.read_only,
117            skip_environment_update: request.skip_environment_update,
118            flags: request.flags,
119            working_directory: request.working_directory,
120            client_terminal: request.client_terminal,
121            client_size: request.client_size,
122            attach_capabilities,
123        }
124    }
125
126    /// Splits out the v2 payload fields and the attach-stream capabilities.
127    #[must_use]
128    pub fn into_ext2_and_capabilities(self) -> (AttachSessionExt2Request, Vec<String>) {
129        (
130            AttachSessionExt2Request {
131                target: self.target,
132                target_spec: self.target_spec,
133                detach_other_clients: self.detach_other_clients,
134                kill_other_clients: self.kill_other_clients,
135                read_only: self.read_only,
136                skip_environment_update: self.skip_environment_update,
137                flags: self.flags,
138                working_directory: self.working_directory,
139                client_terminal: self.client_terminal,
140                client_size: self.client_size,
141            },
142            self.attach_capabilities,
143        )
144    }
145}
146
147/// Request payload for `switch-client`.
148#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
149pub struct SwitchClientRequest {
150    /// The exact target session name.
151    pub target: SessionName,
152}
153
154/// Extended request payload for `switch-client`.
155#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
156pub struct SwitchClientExtRequest {
157    /// The optional exact target session name.
158    pub target: Option<SessionName>,
159    /// The optional key table to set for the attached client.
160    pub key_table: Option<String>,
161}
162
163/// Further-extended request payload for `switch-client`.
164#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
165pub struct SwitchClientExt2Request {
166    /// The optional exact target session name.
167    pub target: Option<SessionName>,
168    /// The optional key table to set for the attached client.
169    #[serde(default)]
170    pub key_table: Option<String>,
171    /// Whether the client's last session should be recalled.
172    #[serde(default)]
173    pub last_session: bool,
174    /// Whether the next session in order should be selected.
175    #[serde(default)]
176    pub next_session: bool,
177    /// Whether the previous session in order should be selected.
178    #[serde(default)]
179    pub previous_session: bool,
180    /// Whether readonly mode should be toggled for the addressed client.
181    #[serde(default)]
182    pub toggle_read_only: bool,
183    /// Reserved legacy field kept for wire compatibility; `switch-client` does not support `-f`.
184    #[serde(default)]
185    pub flags: Option<Vec<String>>,
186    /// Optional tmux list-sorting token used by `-n` and `-p`.
187    #[serde(default)]
188    pub sort_order: Option<String>,
189    /// Whether client environment updates should be skipped.
190    #[serde(default)]
191    pub skip_environment_update: bool,
192}
193
194/// Further-extended request payload for `switch-client`.
195#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
196pub struct SwitchClientExt3Request {
197    /// The optional target-client identifier or `=`.
198    #[serde(default)]
199    pub target_client: Option<String>,
200    /// The optional tmux target string, including pane or window targets.
201    #[serde(default)]
202    pub target: Option<String>,
203    /// The optional key table to set for the attached client.
204    #[serde(default)]
205    pub key_table: Option<String>,
206    /// Whether the client's last session should be recalled.
207    #[serde(default)]
208    pub last_session: bool,
209    /// Whether the next session in order should be selected.
210    #[serde(default)]
211    pub next_session: bool,
212    /// Whether the previous session in order should be selected.
213    #[serde(default)]
214    pub previous_session: bool,
215    /// Whether readonly mode should be toggled for the addressed client.
216    #[serde(default)]
217    pub toggle_read_only: bool,
218    /// Optional tmux list-sorting token used by `-n` and `-p`.
219    #[serde(default)]
220    pub sort_order: Option<String>,
221    /// Whether client environment updates should be skipped.
222    #[serde(default)]
223    pub skip_environment_update: bool,
224    /// Whether zoom should be preserved when switching panes.
225    #[serde(default)]
226    pub zoom: bool,
227}
228
229/// Request payload for `detach-client`.
230#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
231pub struct DetachClientRequest;
232
233/// Extended request payload for `detach-client`.
234#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
235pub struct DetachClientExtRequest {
236    /// The optional target-client identifier or `=`.
237    #[serde(default)]
238    pub target_client: Option<String>,
239    /// Whether all other clients should be detached instead.
240    #[serde(default)]
241    pub all_other_clients: bool,
242    /// The optional target session whose clients should all be detached.
243    #[serde(default)]
244    pub target_session: Option<SessionName>,
245    /// Whether targeted clients should be killed after detach.
246    #[serde(default)]
247    pub kill_on_detach: bool,
248    /// Optional client-local shell command to run before detaching.
249    #[serde(default)]
250    pub exec_command: Option<String>,
251}
252
253/// Request payload for `refresh-client`.
254#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
255pub struct RefreshClientRequest {
256    /// The optional target-client identifier or `=`.
257    #[serde(default)]
258    pub target_client: Option<String>,
259    /// Reserved wire-v5 field for a client-pan adjustment.
260    ///
261    /// RMUX 0.9 does not expose client panning and rejects a populated value
262    /// fail-closed when received from an older client.
263    #[serde(default)]
264    pub adjustment: Option<u32>,
265    /// Reserved wire-v5 field for clearing client panning.
266    #[serde(default)]
267    pub clear_pan: bool,
268    /// Reserved wire-v5 field for panning the client view left.
269    #[serde(default)]
270    pub pan_left: bool,
271    /// Reserved wire-v5 field for panning the client view right.
272    #[serde(default)]
273    pub pan_right: bool,
274    /// Reserved wire-v5 field for panning the client view up.
275    #[serde(default)]
276    pub pan_up: bool,
277    /// Reserved wire-v5 field for panning the client view down.
278    #[serde(default)]
279    pub pan_down: bool,
280    /// Whether only the status line should be redrawn.
281    #[serde(default)]
282    pub status_only: bool,
283    /// Whether the client clipboard should be queried.
284    #[serde(default)]
285    pub clipboard_query: bool,
286    /// Optional client-flag string from `-f`.
287    #[serde(default)]
288    pub flags: Option<String>,
289    /// Optional client-flag string from `-F`, which tmux treats as an alias for `-f`.
290    #[serde(default)]
291    pub flags_alias: Option<String>,
292    /// Reserved wire-v5 field for control-mode subscription updates.
293    ///
294    /// RMUX 0.9 does not expose `refresh-client -A` and rejects non-empty
295    /// values fail-closed when received from an older client.
296    #[serde(default)]
297    pub subscriptions: Vec<String>,
298    /// Reserved wire-v5 field for control-mode subscription definitions.
299    ///
300    /// RMUX 0.9 does not expose `refresh-client -B` and rejects non-empty
301    /// values fail-closed when received from an older client.
302    #[serde(default)]
303    pub subscriptions_format: Vec<String>,
304    /// Optional control-mode size string from `-C`.
305    #[serde(default)]
306    pub control_size: Option<String>,
307    /// Reserved wire-v5 field for control-mode colour reports.
308    ///
309    /// RMUX 0.9 does not expose `refresh-client -r` and rejects a populated
310    /// value fail-closed when received from an older client.
311    #[serde(default)]
312    pub colour_report: Option<String>,
313}
314
315/// Request payload for `list-clients`.
316#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
317pub struct ListClientsRequest {
318    /// Optional custom output format.
319    #[serde(default)]
320    pub format: Option<String>,
321    /// Optional filter expression.
322    #[serde(default)]
323    pub filter: Option<String>,
324    /// Optional sort-order token.
325    #[serde(default)]
326    pub sort_order: Option<String>,
327    /// Whether the listing should be reversed.
328    #[serde(default)]
329    pub reversed: bool,
330    /// Optional session filter.
331    #[serde(default)]
332    pub target_session: Option<SessionName>,
333}
334
335/// Request payload for `suspend-client`.
336#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
337pub struct SuspendClientRequest {
338    /// The optional target-client identifier or `=`.
339    #[serde(default)]
340    pub target_client: Option<String>,
341}