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}