1pub use super::generated_api::api::{
2 action::{
3 action::OptionalPayload,
4 command_or_plugin::CommandOrPluginType,
5 pane_run::RunType,
6 run_plugin_location_data::LocationData,
7 run_plugin_or_alias::PluginType,
8 Action as ProtobufAction,
9 ActionName as ProtobufActionName,
10 AreFloatingPanesVisiblePayload,
11 BareKey as ProtobufBareKey,
12 CommandOrPlugin as ProtobufCommandOrPlugin,
14 DumpScreenPayload,
15 EditFilePayload,
16 FloatingPaneCoordinates as ProtobufFloatingPaneCoordinates,
17 FloatingPaneLayout as ProtobufFloatingPaneLayout,
18 FloatingPlacement as ProtobufFloatingPlacement,
19 GoToTabNamePayload,
20 HideFloatingPanesPayload,
21 IdAndName,
22 InPlaceConfig as ProtobufInPlaceConfig,
23 KeyModifier as ProtobufKeyModifier,
24 KeyWithModifier as ProtobufKeyWithModifier,
25 LaunchOrFocusPluginPayload,
26 LayoutConstraint as ProtobufLayoutConstraint,
27 LayoutConstraintFloatingPair as ProtobufLayoutConstraintFloatingPair,
28 LayoutConstraintTiledPair as ProtobufLayoutConstraintTiledPair,
29 LayoutConstraintWithValue as ProtobufLayoutConstraintWithValue,
30 MouseEventPayload as ProtobufMouseEventPayload,
31 MovePanePayload,
32 MoveTabDirection as ProtobufMoveTabDirection,
33 NameAndValue as ProtobufNameAndValue,
34 NewBlockingPanePayload,
35 NewFloatingPanePayload,
36 NewInPlacePanePayload,
37 NewPanePayload,
38 NewPanePlacement as ProtobufNewPanePlacement,
39 NewPluginPanePayload,
40 NewTabPayload,
41 NewTiledPanePayload,
42 OverrideLayoutPayload,
43 PaneId as ProtobufPaneId,
44 PaneIdAndShouldFloat,
45 PaneRun as ProtobufPaneRun,
46 PercentOrFixed as ProtobufPercentOrFixed,
47 PluginAlias as ProtobufPluginAlias,
48 PluginConfiguration as ProtobufPluginConfiguration,
49 PluginTag as ProtobufPluginTag,
50 PluginUserConfiguration as ProtobufPluginUserConfiguration,
51 Position as ProtobufPosition,
52 RunCommandAction as ProtobufRunCommandAction,
53 RunEditFileAction as ProtobufRunEditFileAction,
54 RunPlugin as ProtobufRunPlugin,
55 RunPluginLocation as ProtobufRunPluginLocation,
56 RunPluginLocationData as ProtobufRunPluginLocationData,
57 RunPluginOrAlias as ProtobufRunPluginOrAlias,
58 ScrollAtPayload,
59 SearchDirection as ProtobufSearchDirection,
60 SearchOption as ProtobufSearchOption,
61 ShowFloatingPanesPayload,
62 SplitDirection as ProtobufSplitDirection,
63 SplitSize as ProtobufSplitSize,
64 StackedPlacement as ProtobufStackedPlacement,
65 SwapFloatingLayout as ProtobufSwapFloatingLayout,
66 SwapTiledLayout as ProtobufSwapTiledLayout,
67 SwitchToModePayload,
68 TabIdAndName,
69 TabLayoutInfo as ProtobufTabLayoutInfo,
70 TiledPaneLayout as ProtobufTiledPaneLayout,
71 TiledPlacement as ProtobufTiledPlacement,
72 UnblockCondition as ProtobufUnblockCondition,
73 WriteCharsPayload,
74 WritePayload,
75 },
76 input_mode::InputMode as ProtobufInputMode,
77 resize::{Resize as ProtobufResize, ResizeDirection as ProtobufResizeDirection},
78};
79use crate::data::{
80 CommandOrPlugin, Direction, FloatingPaneCoordinates, InputMode, KeyWithModifier,
81 NewPanePlacement, PaneId, PluginTag, ResizeStrategy, UnblockCondition,
82};
83use crate::errors::prelude::*;
84use crate::input::actions::Action;
85use crate::input::actions::{SearchDirection, SearchOption};
86use crate::input::command::{OpenFilePayload, RunCommandAction};
87use crate::input::layout::SplitSize;
88use crate::input::layout::{
89 FloatingPaneLayout, LayoutConstraint, PercentOrFixed, PluginAlias, PluginUserConfiguration,
90 Run, RunPlugin, RunPluginLocation, RunPluginOrAlias, SplitDirection, SwapFloatingLayout,
91 SwapTiledLayout, TabLayoutInfo, TiledPaneLayout,
92};
93use crate::input::mouse::{MouseEvent, MouseEventType};
94use crate::position::Position;
95
96use std::collections::BTreeMap;
97use std::convert::TryFrom;
98use std::path::PathBuf;
99
100impl TryFrom<ProtobufAction> for Action {
101 type Error = &'static str;
102 fn try_from(protobuf_action: ProtobufAction) -> Result<Self, &'static str> {
103 match ProtobufActionName::from_i32(protobuf_action.name) {
104 Some(ProtobufActionName::Quit) => match protobuf_action.optional_payload {
105 Some(_) => Err("The Quit Action should not have a payload"),
106 None => Ok(Action::Quit),
107 },
108 Some(ProtobufActionName::Write) => match protobuf_action.optional_payload {
109 Some(OptionalPayload::WritePayload(write_payload)) => {
110 let key_with_modifier = write_payload
111 .key_with_modifier
112 .and_then(|k| k.try_into().ok());
113 Ok(Action::Write {
114 key_with_modifier,
115 bytes: write_payload.bytes_to_write,
116 is_kitty_keyboard_protocol: write_payload.is_kitty_keyboard_protocol,
117 })
118 },
119 _ => Err("Wrong payload for Action::Write"),
120 },
121 Some(ProtobufActionName::WriteChars) => match protobuf_action.optional_payload {
122 Some(OptionalPayload::WriteCharsPayload(write_chars_payload)) => {
123 Ok(Action::WriteChars {
124 chars: write_chars_payload.chars,
125 })
126 },
127 _ => Err("Wrong payload for Action::WriteChars"),
128 },
129 Some(ProtobufActionName::SwitchToMode) => match protobuf_action.optional_payload {
130 Some(OptionalPayload::SwitchToModePayload(switch_to_mode_payload)) => {
131 let input_mode: InputMode =
132 ProtobufInputMode::from_i32(switch_to_mode_payload.input_mode)
133 .ok_or("Malformed input mode for SwitchToMode Action")?
134 .try_into()?;
135 Ok(Action::SwitchToMode { input_mode })
136 },
137 _ => Err("Wrong payload for Action::SwitchToModePayload"),
138 },
139 Some(ProtobufActionName::SwitchModeForAllClients) => {
140 match protobuf_action.optional_payload {
141 Some(OptionalPayload::SwitchModeForAllClientsPayload(
142 switch_to_mode_payload,
143 )) => {
144 let input_mode: InputMode =
145 ProtobufInputMode::from_i32(switch_to_mode_payload.input_mode)
146 .ok_or("Malformed input mode for SwitchToMode Action")?
147 .try_into()?;
148 Ok(Action::SwitchModeForAllClients { input_mode })
149 },
150 _ => Err("Wrong payload for Action::SwitchModeForAllClients"),
151 }
152 },
153 Some(ProtobufActionName::Resize) => match protobuf_action.optional_payload {
154 Some(OptionalPayload::ResizePayload(resize_payload)) => {
155 let resize_strategy: ResizeStrategy = resize_payload.try_into()?;
156 Ok(Action::Resize {
157 resize: resize_strategy.resize,
158 direction: resize_strategy.direction,
159 })
160 },
161 _ => Err("Wrong payload for Action::Resize"),
162 },
163 Some(ProtobufActionName::FocusNextPane) => match protobuf_action.optional_payload {
164 Some(_) => Err("FocusNextPane should not have a payload"),
165 None => Ok(Action::FocusNextPane),
166 },
167 Some(ProtobufActionName::FocusPreviousPane) => match protobuf_action.optional_payload {
168 Some(_) => Err("FocusPreviousPane should not have a payload"),
169 None => Ok(Action::FocusPreviousPane),
170 },
171 Some(ProtobufActionName::SwitchFocus) => match protobuf_action.optional_payload {
172 Some(_) => Err("SwitchFocus should not have a payload"),
173 None => Ok(Action::SwitchFocus),
174 },
175 Some(ProtobufActionName::MoveFocus) => match protobuf_action.optional_payload {
176 Some(OptionalPayload::MoveFocusPayload(move_focus_payload)) => {
177 let direction: Direction =
178 ProtobufResizeDirection::from_i32(move_focus_payload)
179 .ok_or("Malformed resize direction for Action::MoveFocus")?
180 .try_into()?;
181 Ok(Action::MoveFocus { direction })
182 },
183 _ => Err("Wrong payload for Action::MoveFocus"),
184 },
185 Some(ProtobufActionName::MoveFocusOrTab) => match protobuf_action.optional_payload {
186 Some(OptionalPayload::MoveFocusOrTabPayload(move_focus_or_tab_payload)) => {
187 let direction: Direction =
188 ProtobufResizeDirection::from_i32(move_focus_or_tab_payload)
189 .ok_or("Malformed resize direction for Action::MoveFocusOrTab")?
190 .try_into()?;
191 Ok(Action::MoveFocusOrTab { direction })
192 },
193 _ => Err("Wrong payload for Action::MoveFocusOrTab"),
194 },
195 Some(ProtobufActionName::MovePane) => match protobuf_action.optional_payload {
196 Some(OptionalPayload::MovePanePayload(payload)) => {
197 let direction: Option<Direction> = payload
198 .direction
199 .and_then(|d| ProtobufResizeDirection::from_i32(d))
200 .and_then(|d| d.try_into().ok());
201 Ok(Action::MovePane { direction })
202 },
203 _ => Err("Wrong payload for Action::MovePane"),
204 },
205 Some(ProtobufActionName::MovePaneBackwards) => match protobuf_action.optional_payload {
206 Some(_) => Err("MovePaneBackwards should not have a payload"),
207 None => Ok(Action::MovePaneBackwards),
208 },
209 Some(ProtobufActionName::ClearScreen) => match protobuf_action.optional_payload {
210 Some(_) => Err("ClearScreen should not have a payload"),
211 None => Ok(Action::ClearScreen),
212 },
213 Some(ProtobufActionName::DumpScreen) => match protobuf_action.optional_payload {
214 Some(OptionalPayload::DumpScreenPayload(payload)) => {
215 let file_path = if payload.dump_to_stdout {
216 None
217 } else {
218 Some(payload.file_path)
219 };
220 let include_scrollback = payload.include_scrollback;
221 let pane_id = payload.pane_id.and_then(|p| p.try_into().ok());
222 Ok(Action::DumpScreen {
223 file_path,
224 include_scrollback,
225 pane_id,
226 ansi: payload.ansi,
227 })
228 },
229 _ => Err("Wrong payload for Action::DumpScreen"),
230 },
231 Some(ProtobufActionName::EditScrollback) => match protobuf_action.optional_payload {
232 Some(_) => Err("EditScrollback should not have a payload"),
233 None => Ok(Action::EditScrollback { ansi: false }),
234 },
235 Some(ProtobufActionName::ScrollUp) => match protobuf_action.optional_payload {
236 Some(_) => Err("ScrollUp should not have a payload"),
237 None => Ok(Action::ScrollUp),
238 },
239 Some(ProtobufActionName::ScrollDown) => match protobuf_action.optional_payload {
240 Some(_) => Err("ScrollDown should not have a payload"),
241 None => Ok(Action::ScrollDown),
242 },
243 Some(ProtobufActionName::ScrollUpAt) => match protobuf_action.optional_payload {
244 Some(OptionalPayload::ScrollUpAtPayload(payload)) => {
245 let position = payload
246 .position
247 .ok_or("ScrollUpAtPayload must have a position")?
248 .try_into()?;
249 Ok(Action::ScrollUpAt { position })
250 },
251 _ => Err("Wrong payload for Action::ScrollUpAt"),
252 },
253 Some(ProtobufActionName::ScrollDownAt) => match protobuf_action.optional_payload {
254 Some(OptionalPayload::ScrollDownAtPayload(payload)) => {
255 let position = payload
256 .position
257 .ok_or("ScrollDownAtPayload must have a position")?
258 .try_into()?;
259 Ok(Action::ScrollDownAt { position })
260 },
261 _ => Err("Wrong payload for Action::ScrollDownAt"),
262 },
263 Some(ProtobufActionName::ScrollToBottom) => match protobuf_action.optional_payload {
264 Some(_) => Err("ScrollToBottom should not have a payload"),
265 None => Ok(Action::ScrollToBottom),
266 },
267 Some(ProtobufActionName::ScrollToTop) => match protobuf_action.optional_payload {
268 Some(_) => Err("ScrollToTop should not have a payload"),
269 None => Ok(Action::ScrollToTop),
270 },
271 Some(ProtobufActionName::PageScrollUp) => match protobuf_action.optional_payload {
272 Some(_) => Err("PageScrollUp should not have a payload"),
273 None => Ok(Action::PageScrollUp),
274 },
275 Some(ProtobufActionName::PageScrollDown) => match protobuf_action.optional_payload {
276 Some(_) => Err("PageScrollDown should not have a payload"),
277 None => Ok(Action::PageScrollDown),
278 },
279 Some(ProtobufActionName::HalfPageScrollUp) => match protobuf_action.optional_payload {
280 Some(_) => Err("HalfPageScrollUp should not have a payload"),
281 None => Ok(Action::HalfPageScrollUp),
282 },
283 Some(ProtobufActionName::HalfPageScrollDown) => {
284 match protobuf_action.optional_payload {
285 Some(_) => Err("HalfPageScrollDown should not have a payload"),
286 None => Ok(Action::HalfPageScrollDown),
287 }
288 },
289 Some(ProtobufActionName::ToggleFocusFullscreen) => {
290 match protobuf_action.optional_payload {
291 Some(_) => Err("ToggleFocusFullscreen should not have a payload"),
292 None => Ok(Action::ToggleFocusFullscreen),
293 }
294 },
295 Some(ProtobufActionName::TogglePaneFrames) => match protobuf_action.optional_payload {
296 Some(_) => Err("TogglePaneFrames should not have a payload"),
297 None => Ok(Action::TogglePaneFrames),
298 },
299 Some(ProtobufActionName::ToggleActiveSyncTab) => {
300 match protobuf_action.optional_payload {
301 Some(_) => Err("ToggleActiveSyncTab should not have a payload"),
302 None => Ok(Action::ToggleActiveSyncTab),
303 }
304 },
305 Some(ProtobufActionName::NewPane) => match protobuf_action.optional_payload {
306 Some(OptionalPayload::NewPanePayload(payload)) => {
307 let direction: Option<Direction> = payload
308 .direction
309 .and_then(|d| ProtobufResizeDirection::from_i32(d))
310 .and_then(|d| d.try_into().ok());
311 let pane_name = payload.pane_name;
312 Ok(Action::NewPane {
313 direction,
314 pane_name,
315 start_suppressed: false,
316 })
317 },
318 _ => Err("Wrong payload for Action::NewPane"),
319 },
320 Some(ProtobufActionName::EditFile) => match protobuf_action.optional_payload {
321 Some(OptionalPayload::EditFilePayload(payload)) => {
322 let file_to_edit = PathBuf::from(payload.file_to_edit);
323 let line_number: Option<usize> = payload.line_number.map(|l| l as usize);
324 let cwd: Option<PathBuf> = payload.cwd.map(|p| PathBuf::from(p));
325 let direction: Option<Direction> = payload
326 .direction
327 .and_then(|d| ProtobufResizeDirection::from_i32(d))
328 .and_then(|d| d.try_into().ok());
329 let near_current_pane = payload.near_current_pane;
330 let should_float = payload.should_float;
331 let should_be_in_place = false;
332 Ok(Action::EditFile {
333 payload: OpenFilePayload::new(file_to_edit, line_number, cwd),
334 direction,
335 floating: should_float,
336 in_place: should_be_in_place,
337 close_replaced_pane: false,
338 start_suppressed: false,
339 coordinates: None,
340 near_current_pane,
341 tab_id: None,
342 })
343 },
344 _ => Err("Wrong payload for Action::NewPane"),
345 },
346 Some(ProtobufActionName::NewFloatingPane) => match protobuf_action.optional_payload {
347 Some(OptionalPayload::NewFloatingPanePayload(payload)) => {
348 let near_current_pane = payload.near_current_pane;
349 if let Some(payload) = payload.command {
350 let pane_name = payload.pane_name.clone();
351 let run_command_action: RunCommandAction = payload.try_into()?;
352 Ok(Action::NewFloatingPane {
353 command: Some(run_command_action),
354 pane_name,
355 coordinates: None,
356 near_current_pane,
357 tab_id: None,
358 })
359 } else {
360 Ok(Action::NewFloatingPane {
361 command: None,
362 pane_name: None,
363 coordinates: None,
364 near_current_pane,
365 tab_id: None,
366 })
367 }
368 },
369 _ => Err("Wrong payload for Action::NewFloatingPane"),
370 },
371 Some(ProtobufActionName::NewTiledPane) => match protobuf_action.optional_payload {
372 Some(OptionalPayload::NewTiledPanePayload(payload)) => {
373 let direction: Option<Direction> = payload
374 .direction
375 .and_then(|d| ProtobufResizeDirection::from_i32(d))
376 .and_then(|d| d.try_into().ok());
377 let near_current_pane = payload.near_current_pane;
378 let borderless = payload.borderless;
379 if let Some(payload) = payload.command {
380 let pane_name = payload.pane_name.clone();
381 let run_command_action: RunCommandAction = payload.try_into()?;
382 Ok(Action::NewTiledPane {
383 direction,
384 command: Some(run_command_action),
385 pane_name,
386 near_current_pane,
387 borderless,
388 tab_id: None,
389 })
390 } else {
391 Ok(Action::NewTiledPane {
392 direction,
393 command: None,
394 pane_name: None,
395 near_current_pane,
396 borderless,
397 tab_id: None,
398 })
399 }
400 },
401 _ => Err("Wrong payload for Action::NewTiledPane"),
402 },
403 Some(ProtobufActionName::TogglePaneEmbedOrFloating) => {
404 match protobuf_action.optional_payload {
405 Some(_) => Err("TogglePaneEmbedOrFloating should not have a payload"),
406 None => Ok(Action::TogglePaneEmbedOrFloating),
407 }
408 },
409 Some(ProtobufActionName::ToggleFloatingPanes) => {
410 match protobuf_action.optional_payload {
411 Some(_) => Err("ToggleFloatingPanes should not have a payload"),
412 None => Ok(Action::ToggleFloatingPanes),
413 }
414 },
415 Some(ProtobufActionName::ShowFloatingPanes) => match protobuf_action.optional_payload {
416 Some(OptionalPayload::ShowFloatingPanesPayload(payload)) => {
417 Ok(Action::ShowFloatingPanes {
418 tab_id: payload.tab_id.map(|id| id as usize),
419 })
420 },
421 None => Ok(Action::ShowFloatingPanes { tab_id: None }),
422 _ => Err("Wrong payload for ShowFloatingPanes"),
423 },
424 Some(ProtobufActionName::HideFloatingPanes) => match protobuf_action.optional_payload {
425 Some(OptionalPayload::HideFloatingPanesPayload(payload)) => {
426 Ok(Action::HideFloatingPanes {
427 tab_id: payload.tab_id.map(|id| id as usize),
428 })
429 },
430 None => Ok(Action::HideFloatingPanes { tab_id: None }),
431 _ => Err("Wrong payload for HideFloatingPanes"),
432 },
433 Some(ProtobufActionName::AreFloatingPanesVisible) => {
434 match protobuf_action.optional_payload {
435 Some(OptionalPayload::AreFloatingPanesVisiblePayload(payload)) => {
436 Ok(Action::AreFloatingPanesVisible {
437 tab_id: payload.tab_id.map(|id| id as usize),
438 })
439 },
440 None => Ok(Action::AreFloatingPanesVisible { tab_id: None }),
441 _ => Err("Wrong payload for AreFloatingPanesVisible"),
442 }
443 },
444 Some(ProtobufActionName::CloseFocus) => match protobuf_action.optional_payload {
445 Some(_) => Err("CloseFocus should not have a payload"),
446 None => Ok(Action::CloseFocus),
447 },
448 Some(ProtobufActionName::PaneNameInput) => match protobuf_action.optional_payload {
449 Some(OptionalPayload::PaneNameInputPayload(bytes)) => {
450 Ok(Action::PaneNameInput { input: bytes })
451 },
452 _ => Err("Wrong payload for Action::PaneNameInput"),
453 },
454 Some(ProtobufActionName::UndoRenamePane) => match protobuf_action.optional_payload {
455 Some(_) => Err("UndoRenamePane should not have a payload"),
456 None => Ok(Action::UndoRenamePane),
457 },
458 Some(ProtobufActionName::NewTab) => {
459 match protobuf_action.optional_payload {
460 Some(OptionalPayload::NewTabPayload(payload)) => {
461 let tiled_layout =
463 payload.tiled_layout.map(|l| l.try_into()).transpose()?;
464
465 let floating_layouts = payload
466 .floating_layouts
467 .into_iter()
468 .map(|l| l.try_into())
469 .collect::<Result<Vec<_>, _>>()?;
470
471 let swap_tiled_layouts = if payload.swap_tiled_layouts.is_empty() {
472 None
473 } else {
474 Some(
475 payload
476 .swap_tiled_layouts
477 .into_iter()
478 .map(|l| l.try_into())
479 .collect::<Result<Vec<_>, _>>()?,
480 )
481 };
482
483 let swap_floating_layouts = if payload.swap_floating_layouts.is_empty() {
484 None
485 } else {
486 Some(
487 payload
488 .swap_floating_layouts
489 .into_iter()
490 .map(|l| l.try_into())
491 .collect::<Result<Vec<_>, _>>()?,
492 )
493 };
494
495 let tab_name = payload.tab_name;
496 let should_change_focus_to_new_tab = payload.should_change_focus_to_new_tab;
497 let cwd = payload.cwd.map(PathBuf::from);
498
499 let initial_panes = if payload.initial_panes.is_empty() {
500 None
501 } else {
502 Some(
503 payload
504 .initial_panes
505 .into_iter()
506 .map(|p| p.try_into())
507 .collect::<Result<Vec<_>, _>>()?,
508 )
509 };
510
511 let first_pane_unblock_condition = payload
512 .first_pane_unblock_condition
513 .and_then(|uc| ProtobufUnblockCondition::from_i32(uc))
514 .and_then(|uc| uc.try_into().ok());
515
516 Ok(Action::NewTab {
517 tiled_layout,
518 floating_layouts,
519 swap_tiled_layouts,
520 swap_floating_layouts,
521 tab_name,
522 should_change_focus_to_new_tab,
523 cwd,
524 initial_panes,
525 first_pane_unblock_condition,
526 })
527 },
528 None => {
529 Ok(Action::NewTab {
532 tiled_layout: None,
533 floating_layouts: vec![],
534 swap_tiled_layouts: None,
535 swap_floating_layouts: None,
536 tab_name: None,
537 should_change_focus_to_new_tab: true,
538 cwd: None,
539 initial_panes: None,
540 first_pane_unblock_condition: None,
541 })
542 },
543 _ => Err("Wrong payload for Action::NewTab"),
544 }
545 },
546 Some(ProtobufActionName::NoOp) => match protobuf_action.optional_payload {
547 Some(_) => Err("NoOp should not have a payload"),
548 None => Ok(Action::NoOp),
549 },
550 Some(ProtobufActionName::GoToNextTab) => match protobuf_action.optional_payload {
551 Some(_) => Err("GoToNextTab should not have a payload"),
552 None => Ok(Action::GoToNextTab),
553 },
554 Some(ProtobufActionName::GoToPreviousTab) => match protobuf_action.optional_payload {
555 Some(_) => Err("GoToPreviousTab should not have a payload"),
556 None => Ok(Action::GoToPreviousTab),
557 },
558 Some(ProtobufActionName::CloseTab) => match protobuf_action.optional_payload {
559 Some(_) => Err("CloseTab should not have a payload"),
560 None => Ok(Action::CloseTab),
561 },
562 Some(ProtobufActionName::GoToTab) => match protobuf_action.optional_payload {
563 Some(OptionalPayload::GoToTabPayload(index)) => Ok(Action::GoToTab { index }),
564 _ => Err("Wrong payload for Action::GoToTab"),
565 },
566 Some(ProtobufActionName::GoToTabName) => match protobuf_action.optional_payload {
567 Some(OptionalPayload::GoToTabNamePayload(payload)) => {
568 let tab_name = payload.tab_name;
569 let create = payload.create;
570 Ok(Action::GoToTabName {
571 name: tab_name,
572 create,
573 })
574 },
575 _ => Err("Wrong payload for Action::GoToTabName"),
576 },
577 Some(ProtobufActionName::ToggleTab) => match protobuf_action.optional_payload {
578 Some(_) => Err("ToggleTab should not have a payload"),
579 None => Ok(Action::ToggleTab),
580 },
581 Some(ProtobufActionName::TabNameInput) => match protobuf_action.optional_payload {
582 Some(OptionalPayload::TabNameInputPayload(bytes)) => {
583 Ok(Action::TabNameInput { input: bytes })
584 },
585 _ => Err("Wrong payload for Action::TabNameInput"),
586 },
587 Some(ProtobufActionName::UndoRenameTab) => match protobuf_action.optional_payload {
588 Some(_) => Err("UndoRenameTab should not have a payload"),
589 None => Ok(Action::UndoRenameTab),
590 },
591 Some(ProtobufActionName::MoveTab) => match protobuf_action.optional_payload {
592 Some(OptionalPayload::MoveTabPayload(move_tab_payload)) => {
593 let direction: Direction = ProtobufMoveTabDirection::from_i32(move_tab_payload)
594 .ok_or("Malformed move tab direction for Action::MoveTab")?
595 .try_into()?;
596 Ok(Action::MoveTab { direction })
597 },
598 _ => Err("Wrong payload for Action::MoveTab"),
599 },
600 Some(ProtobufActionName::Run) => match protobuf_action.optional_payload {
601 Some(OptionalPayload::RunPayload(run_command_action)) => {
602 let run_command_action = run_command_action.try_into()?;
603 Ok(Action::Run {
604 command: run_command_action,
605 near_current_pane: false,
606 })
607 },
608 _ => Err("Wrong payload for Action::Run"),
609 },
610 Some(ProtobufActionName::Detach) => match protobuf_action.optional_payload {
611 Some(_) => Err("Detach should not have a payload"),
612 None => Ok(Action::Detach),
613 },
614 Some(ProtobufActionName::SetDarkTheme) => match protobuf_action.optional_payload {
615 Some(_) => Err("SetDarkTheme should not have a payload"),
616 None => Ok(Action::SetDarkTheme),
617 },
618 Some(ProtobufActionName::SetLightTheme) => match protobuf_action.optional_payload {
619 Some(_) => Err("SetLightTheme should not have a payload"),
620 None => Ok(Action::SetLightTheme),
621 },
622 Some(ProtobufActionName::ToggleTheme) => match protobuf_action.optional_payload {
623 Some(_) => Err("ToggleTheme should not have a payload"),
624 None => Ok(Action::ToggleTheme),
625 },
626 Some(ProtobufActionName::LeftClick) => match protobuf_action.optional_payload {
627 Some(OptionalPayload::LeftClickPayload(payload)) => {
628 let position = payload.try_into()?;
629 Ok(Action::MouseEvent {
630 event: MouseEvent::new_left_press_event(position),
631 })
632 },
633 _ => Err("Wrong payload for Action::LeftClick"),
634 },
635 Some(ProtobufActionName::RightClick) => match protobuf_action.optional_payload {
636 Some(OptionalPayload::RightClickPayload(payload)) => {
637 let position = payload.try_into()?;
638 Ok(Action::MouseEvent {
639 event: MouseEvent::new_right_press_event(position),
640 })
641 },
642 _ => Err("Wrong payload for Action::RightClick"),
643 },
644 Some(ProtobufActionName::MiddleClick) => match protobuf_action.optional_payload {
645 Some(OptionalPayload::MiddleClickPayload(payload)) => {
646 let position = payload.try_into()?;
647 Ok(Action::MouseEvent {
648 event: MouseEvent::new_middle_press_event(position),
649 })
650 },
651 _ => Err("Wrong payload for Action::MiddleClick"),
652 },
653 Some(ProtobufActionName::LaunchOrFocusPlugin) => {
654 match protobuf_action.optional_payload {
655 Some(OptionalPayload::LaunchOrFocusPluginPayload(payload)) => {
656 let configuration: PluginUserConfiguration = payload
657 .plugin_configuration
658 .and_then(|p| PluginUserConfiguration::try_from(p).ok())
659 .unwrap_or_default();
660 let run_plugin_or_alias = RunPluginOrAlias::from_url(
661 &payload.plugin_url.as_str(),
662 &Some(configuration.inner().clone()),
663 None,
664 None,
665 )
666 .map_err(|_| "Malformed LaunchOrFocusPlugin payload")?;
667 let should_float = payload.should_float;
668 let move_to_focused_tab = payload.move_to_focused_tab;
669 let should_open_in_place = payload.should_open_in_place;
670 let skip_plugin_cache = payload.skip_plugin_cache;
671 Ok(Action::LaunchOrFocusPlugin {
672 plugin: run_plugin_or_alias,
673 should_float,
674 move_to_focused_tab,
675 should_open_in_place,
676 close_replaced_pane: false,
677 skip_cache: skip_plugin_cache,
678 tab_id: None,
679 })
680 },
681 _ => Err("Wrong payload for Action::LaunchOrFocusPlugin"),
682 }
683 },
684 Some(ProtobufActionName::LaunchPlugin) => match protobuf_action.optional_payload {
685 Some(OptionalPayload::LaunchOrFocusPluginPayload(payload)) => {
686 let configuration: PluginUserConfiguration = payload
687 .plugin_configuration
688 .and_then(|p| PluginUserConfiguration::try_from(p).ok())
689 .unwrap_or_default();
690 let run_plugin_or_alias = RunPluginOrAlias::from_url(
691 &payload.plugin_url.as_str(),
692 &Some(configuration.inner().clone()),
693 None,
694 None,
695 )
696 .map_err(|_| "Malformed LaunchOrFocusPlugin payload")?;
697 let should_float = payload.should_float;
698 let _move_to_focused_tab = payload.move_to_focused_tab; let should_open_in_place = payload.should_open_in_place;
701 let skip_plugin_cache = payload.skip_plugin_cache;
702 Ok(Action::LaunchPlugin {
703 plugin: run_plugin_or_alias,
704 should_float,
705 should_open_in_place,
706 close_replaced_pane: false,
707 skip_cache: skip_plugin_cache,
708 cwd: None,
709 tab_id: None,
710 })
711 },
712 _ => Err("Wrong payload for Action::LaunchOrFocusPlugin"),
713 },
714 Some(ProtobufActionName::LeftMouseRelease) => match protobuf_action.optional_payload {
715 Some(OptionalPayload::LeftMouseReleasePayload(payload)) => {
716 let position = payload.try_into()?;
717 Ok(Action::MouseEvent {
718 event: MouseEvent::new_left_release_event(position),
719 })
720 },
721 _ => Err("Wrong payload for Action::LeftMouseRelease"),
722 },
723 Some(ProtobufActionName::RightMouseRelease) => match protobuf_action.optional_payload {
724 Some(OptionalPayload::RightMouseReleasePayload(payload)) => {
725 let position = payload.try_into()?;
726 Ok(Action::MouseEvent {
727 event: MouseEvent::new_right_release_event(position),
728 })
729 },
730 _ => Err("Wrong payload for Action::RightMouseRelease"),
731 },
732 Some(ProtobufActionName::MiddleMouseRelease) => {
733 match protobuf_action.optional_payload {
734 Some(OptionalPayload::MiddleMouseReleasePayload(payload)) => {
735 let position = payload.try_into()?;
736 Ok(Action::MouseEvent {
737 event: MouseEvent::new_middle_release_event(position),
738 })
739 },
740 _ => Err("Wrong payload for Action::MiddleMouseRelease"),
741 }
742 },
743 Some(ProtobufActionName::MouseEvent) => match protobuf_action.optional_payload {
744 Some(OptionalPayload::MouseEventPayload(payload)) => {
745 let event = payload.try_into()?;
746 Ok(Action::MouseEvent { event })
747 },
748 _ => Err("Wrong payload for Action::MouseEvent"),
749 },
750 Some(ProtobufActionName::SearchInput) => match protobuf_action.optional_payload {
751 Some(OptionalPayload::SearchInputPayload(payload)) => {
752 Ok(Action::SearchInput { input: payload })
753 },
754 _ => Err("Wrong payload for Action::SearchInput"),
755 },
756 Some(ProtobufActionName::Search) => match protobuf_action.optional_payload {
757 Some(OptionalPayload::SearchPayload(search_direction)) => Ok(Action::Search {
758 direction: ProtobufSearchDirection::from_i32(search_direction)
759 .ok_or("Malformed payload for Action::Search")?
760 .try_into()?,
761 }),
762 _ => Err("Wrong payload for Action::Search"),
763 },
764 Some(ProtobufActionName::SearchToggleOption) => {
765 match protobuf_action.optional_payload {
766 Some(OptionalPayload::SearchToggleOptionPayload(search_option)) => {
767 Ok(Action::SearchToggleOption {
768 option: ProtobufSearchOption::from_i32(search_option)
769 .ok_or("Malformed payload for Action::SearchToggleOption")?
770 .try_into()?,
771 })
772 },
773 _ => Err("Wrong payload for Action::SearchToggleOption"),
774 }
775 },
776 Some(ProtobufActionName::ToggleMouseMode) => match protobuf_action.optional_payload {
777 Some(_) => Err("ToggleMouseMode should not have a payload"),
778 None => Ok(Action::ToggleMouseMode),
779 },
780 Some(ProtobufActionName::PreviousSwapLayout) => {
781 match protobuf_action.optional_payload {
782 Some(_) => Err("PreviousSwapLayout should not have a payload"),
783 None => Ok(Action::PreviousSwapLayout),
784 }
785 },
786 Some(ProtobufActionName::NextSwapLayout) => match protobuf_action.optional_payload {
787 Some(_) => Err("NextSwapLayout should not have a payload"),
788 None => Ok(Action::NextSwapLayout),
789 },
790 Some(ProtobufActionName::OverrideLayout) => match protobuf_action.optional_payload {
791 Some(OptionalPayload::OverrideLayoutPayload(payload)) => {
792 Ok(Action::OverrideLayout {
793 tabs: payload
794 .tabs
795 .into_iter()
796 .map(|t| t.try_into())
797 .collect::<Result<Vec<_>, _>>()?,
798 retain_existing_terminal_panes: payload.retain_existing_terminal_panes,
799 retain_existing_plugin_panes: payload.retain_existing_plugin_panes,
800 apply_only_to_active_tab: payload.apply_only_to_active_tab,
801 })
802 },
803 Some(_) => Err("Mismatched payload for OverrideLayout"),
804 None => Err("Missing payload for OverrideLayout"),
805 },
806 Some(ProtobufActionName::QueryTabNames) => match protobuf_action.optional_payload {
807 Some(_) => Err("QueryTabNames should not have a payload"),
808 None => Ok(Action::QueryTabNames),
809 },
810 Some(ProtobufActionName::NewTiledPluginPane) => {
811 match protobuf_action.optional_payload {
812 Some(OptionalPayload::NewTiledPluginPanePayload(payload)) => {
813 let run_plugin_location =
814 RunPluginLocation::parse(&payload.plugin_url, None)
815 .map_err(|_| "Malformed NewTiledPluginPane payload")?;
816 let run_plugin = RunPluginOrAlias::RunPlugin(RunPlugin {
817 location: run_plugin_location,
818 _allow_exec_host_cmd: false,
819 configuration: PluginUserConfiguration::default(),
820 ..Default::default()
821 });
822 let pane_name = payload.pane_name;
823 let skip_plugin_cache = payload.skip_plugin_cache;
824 Ok(Action::NewTiledPluginPane {
825 plugin: run_plugin,
826 pane_name,
827 skip_cache: skip_plugin_cache,
828 cwd: None,
829 tab_id: None,
830 })
831 },
832 _ => Err("Wrong payload for Action::NewTiledPluginPane"),
833 }
834 },
835 Some(ProtobufActionName::NewFloatingPluginPane) => {
836 match protobuf_action.optional_payload {
837 Some(OptionalPayload::NewFloatingPluginPanePayload(payload)) => {
838 let run_plugin_location =
839 RunPluginLocation::parse(&payload.plugin_url, None)
840 .map_err(|_| "Malformed NewTiledPluginPane payload")?;
841 let run_plugin = RunPluginOrAlias::RunPlugin(RunPlugin {
842 location: run_plugin_location,
843 _allow_exec_host_cmd: false,
844 configuration: PluginUserConfiguration::default(),
845 ..Default::default()
846 });
847 let pane_name = payload.pane_name;
848 let skip_plugin_cache = payload.skip_plugin_cache;
849 Ok(Action::NewFloatingPluginPane {
850 plugin: run_plugin,
851 pane_name,
852 skip_cache: skip_plugin_cache,
853 cwd: None,
854 coordinates: None,
855 tab_id: None,
856 })
857 },
858 _ => Err("Wrong payload for Action::MiddleClick"),
859 }
860 },
861 Some(ProtobufActionName::StartOrReloadPlugin) => {
862 match protobuf_action.optional_payload {
863 Some(OptionalPayload::StartOrReloadPluginPayload(payload)) => {
864 let run_plugin_or_alias =
865 RunPluginOrAlias::from_url(&payload.as_str(), &None, None, None)
866 .map_err(|_| "Malformed LaunchOrFocusPlugin payload")?;
867
868 Ok(Action::StartOrReloadPlugin {
869 plugin: run_plugin_or_alias,
870 })
871 },
872 _ => Err("Wrong payload for Action::StartOrReloadPlugin"),
873 }
874 },
875 Some(ProtobufActionName::CloseTerminalPane) => match protobuf_action.optional_payload {
876 Some(OptionalPayload::CloseTerminalPanePayload(payload)) => {
877 Ok(Action::CloseTerminalPane { pane_id: payload })
878 },
879 _ => Err("Wrong payload for Action::CloseTerminalPane"),
880 },
881 Some(ProtobufActionName::ClosePluginPane) => match protobuf_action.optional_payload {
882 Some(OptionalPayload::ClosePluginPanePayload(payload)) => {
883 Ok(Action::ClosePluginPane { pane_id: payload })
884 },
885 _ => Err("Wrong payload for Action::ClosePluginPane"),
886 },
887 Some(ProtobufActionName::FocusTerminalPaneWithId) => {
888 match protobuf_action.optional_payload {
889 Some(OptionalPayload::FocusTerminalPaneWithIdPayload(payload)) => {
890 let terminal_pane_id = payload.pane_id;
891 let should_float_if_hidden = payload.should_float;
892 let should_be_in_place_if_hidden = payload.should_be_in_place;
893 Ok(Action::FocusTerminalPaneWithId {
894 pane_id: terminal_pane_id,
895 should_float_if_hidden,
896 should_be_in_place_if_hidden,
897 })
898 },
899 _ => Err("Wrong payload for Action::FocusTerminalPaneWithId"),
900 }
901 },
902 Some(ProtobufActionName::FocusPluginPaneWithId) => {
903 match protobuf_action.optional_payload {
904 Some(OptionalPayload::FocusPluginPaneWithIdPayload(payload)) => {
905 let plugin_pane_id = payload.pane_id;
906 let should_float_if_hidden = payload.should_float;
907 let should_be_in_place_if_hidden = payload.should_be_in_place;
908 Ok(Action::FocusPluginPaneWithId {
909 pane_id: plugin_pane_id,
910 should_float_if_hidden,
911 should_be_in_place_if_hidden,
912 })
913 },
914 _ => Err("Wrong payload for Action::FocusPluginPaneWithId"),
915 }
916 },
917 Some(ProtobufActionName::RenameTerminalPane) => {
918 match protobuf_action.optional_payload {
919 Some(OptionalPayload::RenameTerminalPanePayload(payload)) => {
920 let terminal_pane_id = payload.id;
921 let new_pane_name = payload.name;
922 Ok(Action::RenameTerminalPane {
923 pane_id: terminal_pane_id,
924 name: new_pane_name,
925 })
926 },
927 _ => Err("Wrong payload for Action::RenameTerminalPane"),
928 }
929 },
930 Some(ProtobufActionName::RenamePluginPane) => match protobuf_action.optional_payload {
931 Some(OptionalPayload::RenamePluginPanePayload(payload)) => {
932 let plugin_pane_id = payload.id;
933 let new_pane_name = payload.name;
934 Ok(Action::RenamePluginPane {
935 pane_id: plugin_pane_id,
936 name: new_pane_name,
937 })
938 },
939 _ => Err("Wrong payload for Action::RenamePluginPane"),
940 },
941 Some(ProtobufActionName::RenameTab) => match protobuf_action.optional_payload {
942 Some(OptionalPayload::RenameTabPayload(payload)) => {
943 let tab_index = payload.id;
944 let new_tab_name = payload.name;
945 Ok(Action::RenameTab {
946 tab_index,
947 name: new_tab_name,
948 })
949 },
950 _ => Err("Wrong payload for Action::RenameTab"),
951 },
952 Some(ProtobufActionName::BreakPane) => match protobuf_action.optional_payload {
953 Some(_) => Err("BreakPane should not have a payload"),
954 None => Ok(Action::BreakPane),
955 },
956 Some(ProtobufActionName::BreakPaneRight) => match protobuf_action.optional_payload {
957 Some(_) => Err("BreakPaneRight should not have a payload"),
958 None => Ok(Action::BreakPaneRight),
959 },
960 Some(ProtobufActionName::BreakPaneLeft) => match protobuf_action.optional_payload {
961 Some(_) => Err("BreakPaneLeft should not have a payload"),
962 None => Ok(Action::BreakPaneLeft),
963 },
964 Some(ProtobufActionName::RenameSession) => match protobuf_action.optional_payload {
965 Some(OptionalPayload::RenameSessionPayload(name)) => {
966 Ok(Action::RenameSession { name })
967 },
968 _ => Err("Wrong payload for Action::RenameSession"),
969 },
970 Some(ProtobufActionName::TogglePanePinned) => match protobuf_action.optional_payload {
971 Some(_) => Err("TogglePanePinned should not have a payload"),
972 None => Ok(Action::TogglePanePinned),
973 },
974 Some(ProtobufActionName::TogglePaneInGroup) => match protobuf_action.optional_payload {
975 Some(_) => Err("TogglePaneInGroup should not have a payload"),
976 None => Ok(Action::TogglePaneInGroup),
977 },
978 Some(ProtobufActionName::ToggleGroupMarking) => {
979 match protobuf_action.optional_payload {
980 Some(_) => Err("ToggleGroupMarking should not have a payload"),
981 None => Ok(Action::ToggleGroupMarking),
982 }
983 },
984 Some(ProtobufActionName::KeybindPipe) => match protobuf_action.optional_payload {
985 Some(_) => Err("KeybindPipe should not have a payload"),
986 None => Ok(Action::KeybindPipe {
988 name: None,
989 payload: None,
990 args: None,
991 plugin: None,
992 configuration: None,
993 launch_new: false,
994 skip_cache: false,
995 floating: None,
996 in_place: None,
997 cwd: None,
998 pane_title: None,
999 plugin_id: None,
1000 }),
1001 },
1002 Some(ProtobufActionName::NewStackedPane) => match protobuf_action.optional_payload {
1003 Some(_) => Err("NewStackedPane should not have a payload"),
1004 None => Ok(Action::NewStackedPane {
1005 command: None,
1006 pane_name: None,
1007 near_current_pane: false,
1008 tab_id: None,
1009 }),
1010 },
1011 Some(ProtobufActionName::NewBlockingPane) => match protobuf_action.optional_payload {
1012 Some(OptionalPayload::NewBlockingPanePayload(payload)) => {
1013 let placement: NewPanePlacement = payload
1014 .placement
1015 .ok_or("NewBlockingPanePayload must have a placement")?
1016 .try_into()?;
1017 let pane_name = payload.pane_name;
1018 let command = payload.command.and_then(|c| c.try_into().ok());
1019 let unblock_condition = payload
1020 .unblock_condition
1021 .and_then(|uc| ProtobufUnblockCondition::from_i32(uc))
1022 .and_then(|uc| uc.try_into().ok());
1023 let near_current_pane = payload.near_current_pane;
1024 Ok(Action::NewBlockingPane {
1025 placement,
1026 pane_name,
1027 command,
1028 unblock_condition,
1029 near_current_pane,
1030 tab_id: None,
1031 })
1032 },
1033 _ => Err("Wrong payload for Action::NewBlockingPane"),
1034 },
1035 Some(ProtobufActionName::NewInPlacePane) => match protobuf_action.optional_payload {
1036 Some(OptionalPayload::NewInPlacePanePayload(payload)) => {
1037 let near_current_pane = payload.near_current_pane;
1038 let pane_id_to_replace =
1039 payload.pane_id_to_replace.and_then(|p| p.try_into().ok());
1040 let close_replaced_pane = payload.close_replace_pane;
1041 if let Some(command) = payload.command {
1042 let pane_name = command.pane_name.clone();
1043 let run_command_action: RunCommandAction = command.try_into()?;
1044 Ok(Action::NewInPlacePane {
1045 command: Some(run_command_action),
1046 pane_name,
1047 near_current_pane,
1048 pane_id_to_replace,
1049 close_replaced_pane,
1050 tab_id: None,
1051 })
1052 } else {
1053 Ok(Action::NewInPlacePane {
1054 command: None,
1055 pane_name: payload.pane_name,
1056 near_current_pane,
1057 pane_id_to_replace,
1058 close_replaced_pane,
1059 tab_id: None,
1060 })
1061 }
1062 },
1063 _ => Err("Wrong payload for Action::NewInPlacePane"),
1064 },
1065 _ => Err("Unknown Action"),
1066 }
1067 }
1068}
1069
1070impl TryFrom<Action> for ProtobufAction {
1071 type Error = &'static str;
1072 fn try_from(action: Action) -> Result<Self, &'static str> {
1073 match action {
1074 Action::Quit => Ok(ProtobufAction {
1075 name: ProtobufActionName::Quit as i32,
1076 optional_payload: None,
1077 }),
1078 Action::Write {
1079 key_with_modifier,
1080 bytes,
1081 is_kitty_keyboard_protocol,
1082 } => {
1083 let protobuf_key_with_modifier = key_with_modifier.and_then(|k| k.try_into().ok());
1084 Ok(ProtobufAction {
1085 name: ProtobufActionName::Write as i32,
1086 optional_payload: Some(OptionalPayload::WritePayload(WritePayload {
1087 key_with_modifier: protobuf_key_with_modifier,
1088 bytes_to_write: bytes,
1089 is_kitty_keyboard_protocol,
1090 })),
1091 })
1092 },
1093 Action::WriteChars {
1094 chars: chars_to_write,
1095 } => Ok(ProtobufAction {
1096 name: ProtobufActionName::WriteChars as i32,
1097 optional_payload: Some(OptionalPayload::WriteCharsPayload(WriteCharsPayload {
1098 chars: chars_to_write,
1099 })),
1100 }),
1101 Action::WriteToPaneId { .. }
1102 | Action::WriteCharsToPaneId { .. }
1103 | Action::Paste { .. }
1104 | Action::GoToTabById { .. }
1105 | Action::CloseTabById { .. }
1106 | Action::RenameTabById { .. }
1107 | Action::ScrollUpByPaneId { .. }
1108 | Action::ScrollDownByPaneId { .. }
1109 | Action::ScrollToTopByPaneId { .. }
1110 | Action::ScrollToBottomByPaneId { .. }
1111 | Action::PageScrollUpByPaneId { .. }
1112 | Action::PageScrollDownByPaneId { .. }
1113 | Action::HalfPageScrollUpByPaneId { .. }
1114 | Action::HalfPageScrollDownByPaneId { .. }
1115 | Action::ResizeByPaneId { .. }
1116 | Action::MovePaneByPaneId { .. }
1117 | Action::MovePaneBackwardsByPaneId { .. }
1118 | Action::ClearScreenByPaneId { .. }
1119 | Action::EditScrollbackByPaneId { .. }
1120 | Action::ToggleFocusFullscreenByPaneId { .. }
1121 | Action::TogglePaneEmbedOrFloatingByPaneId { .. }
1122 | Action::CloseFocusByPaneId { .. }
1123 | Action::RenamePaneByPaneId { .. }
1124 | Action::UndoRenamePaneByPaneId { .. }
1125 | Action::TogglePanePinnedByPaneId { .. }
1126 | Action::FocusPaneByPaneId { .. }
1127 | Action::UndoRenameTabByTabId { .. }
1128 | Action::ToggleActiveSyncTabByTabId { .. }
1129 | Action::ToggleFloatingPanesByTabId { .. }
1130 | Action::PreviousSwapLayoutByTabId { .. }
1131 | Action::NextSwapLayoutByTabId { .. }
1132 | Action::MoveTabByTabId { .. } => {
1133 Err("These are CLI-only actions, not available in keybindings")
1134 },
1135 Action::SwitchToMode { input_mode } => {
1136 let input_mode: ProtobufInputMode = input_mode.try_into()?;
1137 Ok(ProtobufAction {
1138 name: ProtobufActionName::SwitchToMode as i32,
1139 optional_payload: Some(OptionalPayload::SwitchToModePayload(
1140 SwitchToModePayload {
1141 input_mode: input_mode as i32,
1142 },
1143 )),
1144 })
1145 },
1146 Action::SwitchModeForAllClients { input_mode } => {
1147 let input_mode: ProtobufInputMode = input_mode.try_into()?;
1148 Ok(ProtobufAction {
1149 name: ProtobufActionName::SwitchModeForAllClients as i32,
1150 optional_payload: Some(OptionalPayload::SwitchModeForAllClientsPayload(
1151 SwitchToModePayload {
1152 input_mode: input_mode as i32,
1153 },
1154 )),
1155 })
1156 },
1157 Action::Resize { resize, direction } => {
1158 let mut resize: ProtobufResize = resize.try_into()?;
1159 resize.direction = direction.and_then(|d| {
1160 let resize_direction: ProtobufResizeDirection = d.try_into().ok()?;
1161 Some(resize_direction as i32)
1162 });
1163 Ok(ProtobufAction {
1164 name: ProtobufActionName::Resize as i32,
1165 optional_payload: Some(OptionalPayload::ResizePayload(resize)),
1166 })
1167 },
1168 Action::FocusNextPane => Ok(ProtobufAction {
1169 name: ProtobufActionName::FocusNextPane as i32,
1170 optional_payload: None,
1171 }),
1172 Action::FocusPreviousPane => Ok(ProtobufAction {
1173 name: ProtobufActionName::FocusPreviousPane as i32,
1174 optional_payload: None,
1175 }),
1176 Action::SwitchFocus => Ok(ProtobufAction {
1177 name: ProtobufActionName::SwitchFocus as i32,
1178 optional_payload: None,
1179 }),
1180 Action::MoveFocus { direction } => {
1181 let direction: ProtobufResizeDirection = direction.try_into()?;
1182 Ok(ProtobufAction {
1183 name: ProtobufActionName::MoveFocus as i32,
1184 optional_payload: Some(OptionalPayload::MoveFocusPayload(direction as i32)),
1185 })
1186 },
1187 Action::MoveFocusOrTab { direction } => {
1188 let direction: ProtobufResizeDirection = direction.try_into()?;
1189 Ok(ProtobufAction {
1190 name: ProtobufActionName::MoveFocusOrTab as i32,
1191 optional_payload: Some(OptionalPayload::MoveFocusOrTabPayload(
1192 direction as i32,
1193 )),
1194 })
1195 },
1196 Action::MovePane { direction } => {
1197 let direction = direction.and_then(|direction| {
1198 let protobuf_direction: ProtobufResizeDirection = direction.try_into().ok()?;
1199 Some(protobuf_direction as i32)
1200 });
1201 Ok(ProtobufAction {
1202 name: ProtobufActionName::MovePane as i32,
1203 optional_payload: Some(OptionalPayload::MovePanePayload(MovePanePayload {
1204 direction,
1205 })),
1206 })
1207 },
1208 Action::MovePaneBackwards => Ok(ProtobufAction {
1209 name: ProtobufActionName::MovePaneBackwards as i32,
1210 optional_payload: None,
1211 }),
1212 Action::ClearScreen => Ok(ProtobufAction {
1213 name: ProtobufActionName::ClearScreen as i32,
1214 optional_payload: None,
1215 }),
1216 Action::DumpScreen {
1217 file_path,
1218 include_scrollback,
1219 pane_id,
1220 ansi,
1221 } => {
1222 let dump_to_stdout = file_path.is_none();
1223 Ok(ProtobufAction {
1224 name: ProtobufActionName::DumpScreen as i32,
1225 optional_payload: Some(OptionalPayload::DumpScreenPayload(DumpScreenPayload {
1226 file_path: file_path.unwrap_or_default(),
1227 include_scrollback,
1228 pane_id: pane_id.and_then(|p| p.try_into().ok()),
1229 dump_to_stdout,
1230 ansi,
1231 })),
1232 })
1233 },
1234 Action::EditScrollback { .. } => Ok(ProtobufAction {
1235 name: ProtobufActionName::EditScrollback as i32,
1236 optional_payload: None,
1237 }),
1238 Action::ScrollUp => Ok(ProtobufAction {
1239 name: ProtobufActionName::ScrollUp as i32,
1240 optional_payload: None,
1241 }),
1242 Action::ScrollUpAt { position } => {
1243 let position: ProtobufPosition = position.try_into()?;
1244 Ok(ProtobufAction {
1245 name: ProtobufActionName::ScrollUpAt as i32,
1246 optional_payload: Some(OptionalPayload::ScrollUpAtPayload(ScrollAtPayload {
1247 position: Some(position),
1248 })),
1249 })
1250 },
1251 Action::ScrollDown => Ok(ProtobufAction {
1252 name: ProtobufActionName::ScrollDown as i32,
1253 optional_payload: None,
1254 }),
1255 Action::ScrollDownAt { position } => {
1256 let position: ProtobufPosition = position.try_into()?;
1257 Ok(ProtobufAction {
1258 name: ProtobufActionName::ScrollDownAt as i32,
1259 optional_payload: Some(OptionalPayload::ScrollDownAtPayload(ScrollAtPayload {
1260 position: Some(position),
1261 })),
1262 })
1263 },
1264 Action::ScrollToBottom => Ok(ProtobufAction {
1265 name: ProtobufActionName::ScrollToBottom as i32,
1266 optional_payload: None,
1267 }),
1268 Action::ScrollToTop => Ok(ProtobufAction {
1269 name: ProtobufActionName::ScrollToTop as i32,
1270 optional_payload: None,
1271 }),
1272 Action::PageScrollUp => Ok(ProtobufAction {
1273 name: ProtobufActionName::PageScrollUp as i32,
1274 optional_payload: None,
1275 }),
1276 Action::PageScrollDown => Ok(ProtobufAction {
1277 name: ProtobufActionName::PageScrollDown as i32,
1278 optional_payload: None,
1279 }),
1280 Action::HalfPageScrollUp => Ok(ProtobufAction {
1281 name: ProtobufActionName::HalfPageScrollUp as i32,
1282 optional_payload: None,
1283 }),
1284 Action::HalfPageScrollDown => Ok(ProtobufAction {
1285 name: ProtobufActionName::HalfPageScrollDown as i32,
1286 optional_payload: None,
1287 }),
1288 Action::ToggleFocusFullscreen => Ok(ProtobufAction {
1289 name: ProtobufActionName::ToggleFocusFullscreen as i32,
1290 optional_payload: None,
1291 }),
1292 Action::TogglePaneFrames => Ok(ProtobufAction {
1293 name: ProtobufActionName::TogglePaneFrames as i32,
1294 optional_payload: None,
1295 }),
1296 Action::ToggleActiveSyncTab => Ok(ProtobufAction {
1297 name: ProtobufActionName::ToggleActiveSyncTab as i32,
1298 optional_payload: None,
1299 }),
1300 Action::NewPane {
1301 direction,
1302 pane_name: new_pane_name,
1303 start_suppressed: _start_suppressed,
1304 } => {
1305 let direction = direction.and_then(|direction| {
1306 let protobuf_direction: ProtobufResizeDirection = direction.try_into().ok()?;
1307 Some(protobuf_direction as i32)
1308 });
1309 Ok(ProtobufAction {
1310 name: ProtobufActionName::NewPane as i32,
1311 optional_payload: Some(OptionalPayload::NewPanePayload(NewPanePayload {
1312 direction,
1313 pane_name: new_pane_name,
1314 })),
1315 })
1316 },
1317 Action::EditFile {
1318 payload: open_file_payload,
1319 direction,
1320 floating: should_float,
1321 in_place: _should_be_in_place,
1322 close_replaced_pane: _close_replaced_pane,
1323 start_suppressed: _start_suppressed,
1324 coordinates: _floating_pane_coordinates,
1325 near_current_pane,
1326 ..
1327 } => {
1328 let file_to_edit = open_file_payload.path.display().to_string();
1329 let cwd = open_file_payload.cwd.map(|cwd| cwd.display().to_string());
1330 let direction: Option<i32> = direction
1331 .and_then(|d| ProtobufResizeDirection::try_from(d).ok())
1332 .map(|d| d as i32);
1333 let line_number = open_file_payload.line_number.map(|l| l as u32);
1334 Ok(ProtobufAction {
1335 name: ProtobufActionName::EditFile as i32,
1336 optional_payload: Some(OptionalPayload::EditFilePayload(EditFilePayload {
1337 file_to_edit,
1338 line_number,
1339 should_float,
1340 direction,
1341 cwd,
1342 near_current_pane,
1343 })),
1344 })
1345 },
1346 Action::NewFloatingPane {
1347 command: run_command_action,
1348 pane_name,
1349 coordinates: _coordinates,
1350 near_current_pane,
1351 ..
1352 } => {
1353 let command = run_command_action.and_then(|r| {
1354 let mut protobuf_run_command_action: ProtobufRunCommandAction =
1355 r.try_into().ok()?;
1356 protobuf_run_command_action.pane_name = pane_name;
1357 Some(protobuf_run_command_action)
1358 });
1359 Ok(ProtobufAction {
1360 name: ProtobufActionName::NewFloatingPane as i32,
1361 optional_payload: Some(OptionalPayload::NewFloatingPanePayload(
1362 NewFloatingPanePayload {
1363 command,
1364 near_current_pane,
1365 },
1366 )),
1367 })
1368 },
1369 Action::NewTiledPane {
1370 direction,
1371 command: run_command_action,
1372 pane_name,
1373 near_current_pane,
1374 borderless,
1375 ..
1376 } => {
1377 let direction = direction.and_then(|direction| {
1378 let protobuf_direction: ProtobufResizeDirection = direction.try_into().ok()?;
1379 Some(protobuf_direction as i32)
1380 });
1381 let command = run_command_action.and_then(|r| {
1382 let mut protobuf_run_command_action: ProtobufRunCommandAction =
1383 r.try_into().ok()?;
1384 let pane_name = pane_name.and_then(|n| n.try_into().ok());
1385 protobuf_run_command_action.pane_name = pane_name;
1386 Some(protobuf_run_command_action)
1387 });
1388 Ok(ProtobufAction {
1389 name: ProtobufActionName::NewTiledPane as i32,
1390 optional_payload: Some(OptionalPayload::NewTiledPanePayload(
1391 NewTiledPanePayload {
1392 direction,
1393 command,
1394 near_current_pane,
1395 borderless,
1396 },
1397 )),
1398 })
1399 },
1400 Action::TogglePaneEmbedOrFloating => Ok(ProtobufAction {
1401 name: ProtobufActionName::TogglePaneEmbedOrFloating as i32,
1402 optional_payload: None,
1403 }),
1404 Action::ToggleFloatingPanes => Ok(ProtobufAction {
1405 name: ProtobufActionName::ToggleFloatingPanes as i32,
1406 optional_payload: None,
1407 }),
1408 Action::ShowFloatingPanes { tab_id } => Ok(ProtobufAction {
1409 name: ProtobufActionName::ShowFloatingPanes as i32,
1410 optional_payload: Some(OptionalPayload::ShowFloatingPanesPayload(
1411 ShowFloatingPanesPayload {
1412 tab_id: tab_id.map(|id| id as u32),
1413 },
1414 )),
1415 }),
1416 Action::HideFloatingPanes { tab_id } => Ok(ProtobufAction {
1417 name: ProtobufActionName::HideFloatingPanes as i32,
1418 optional_payload: Some(OptionalPayload::HideFloatingPanesPayload(
1419 HideFloatingPanesPayload {
1420 tab_id: tab_id.map(|id| id as u32),
1421 },
1422 )),
1423 }),
1424 Action::AreFloatingPanesVisible { tab_id } => Ok(ProtobufAction {
1425 name: ProtobufActionName::AreFloatingPanesVisible as i32,
1426 optional_payload: Some(OptionalPayload::AreFloatingPanesVisiblePayload(
1427 AreFloatingPanesVisiblePayload {
1428 tab_id: tab_id.map(|id| id as u32),
1429 },
1430 )),
1431 }),
1432 Action::CloseFocus => Ok(ProtobufAction {
1433 name: ProtobufActionName::CloseFocus as i32,
1434 optional_payload: None,
1435 }),
1436 Action::PaneNameInput { input: bytes } => Ok(ProtobufAction {
1437 name: ProtobufActionName::PaneNameInput as i32,
1438 optional_payload: Some(OptionalPayload::PaneNameInputPayload(bytes)),
1439 }),
1440 Action::UndoRenamePane => Ok(ProtobufAction {
1441 name: ProtobufActionName::UndoRenamePane as i32,
1442 optional_payload: None,
1443 }),
1444 Action::NewTab {
1445 tiled_layout,
1446 floating_layouts,
1447 swap_tiled_layouts,
1448 swap_floating_layouts,
1449 tab_name,
1450 should_change_focus_to_new_tab,
1451 cwd,
1452 initial_panes,
1453 first_pane_unblock_condition,
1454 } => {
1455 let protobuf_tiled_layout = tiled_layout
1457 .as_ref()
1458 .map(|l| l.clone().try_into())
1459 .transpose()?;
1460
1461 let protobuf_floating_layouts = floating_layouts
1462 .iter()
1463 .map(|l| l.clone().try_into())
1464 .collect::<Result<Vec<_>, _>>()?;
1465
1466 let protobuf_swap_tiled_layouts = swap_tiled_layouts
1467 .as_ref()
1468 .map(|layouts| {
1469 layouts
1470 .iter()
1471 .map(|l| l.clone().try_into())
1472 .collect::<Result<Vec<_>, _>>()
1473 })
1474 .transpose()?
1475 .unwrap_or_default();
1476
1477 let protobuf_swap_floating_layouts = swap_floating_layouts
1478 .as_ref()
1479 .map(|layouts| {
1480 layouts
1481 .iter()
1482 .map(|l| l.clone().try_into())
1483 .collect::<Result<Vec<_>, _>>()
1484 })
1485 .transpose()?
1486 .unwrap_or_default();
1487
1488 let cwd_string = cwd.as_ref().map(|p| p.display().to_string());
1489
1490 let protobuf_initial_panes = initial_panes
1491 .as_ref()
1492 .map(|panes| {
1493 panes
1494 .iter()
1495 .map(|p| p.clone().try_into())
1496 .collect::<Result<Vec<_>, _>>()
1497 })
1498 .transpose()?
1499 .unwrap_or_default();
1500
1501 let protobuf_first_pane_unblock_condition = first_pane_unblock_condition
1502 .map(|uc| {
1503 let protobuf_uc: ProtobufUnblockCondition = uc.try_into().ok()?;
1504 Some(protobuf_uc as i32)
1505 })
1506 .flatten();
1507
1508 Ok(ProtobufAction {
1509 name: ProtobufActionName::NewTab as i32,
1510 optional_payload: Some(OptionalPayload::NewTabPayload(NewTabPayload {
1511 tiled_layout: protobuf_tiled_layout,
1512 floating_layouts: protobuf_floating_layouts,
1513 swap_tiled_layouts: protobuf_swap_tiled_layouts,
1514 swap_floating_layouts: protobuf_swap_floating_layouts,
1515 tab_name: tab_name.clone(),
1516 should_change_focus_to_new_tab,
1517 cwd: cwd_string,
1518 initial_panes: protobuf_initial_panes,
1519 first_pane_unblock_condition: protobuf_first_pane_unblock_condition,
1520 })),
1521 })
1522 },
1523 Action::GoToNextTab => Ok(ProtobufAction {
1524 name: ProtobufActionName::GoToNextTab as i32,
1525 optional_payload: None,
1526 }),
1527 Action::GoToPreviousTab => Ok(ProtobufAction {
1528 name: ProtobufActionName::GoToPreviousTab as i32,
1529 optional_payload: None,
1530 }),
1531 Action::CloseTab => Ok(ProtobufAction {
1532 name: ProtobufActionName::CloseTab as i32,
1533 optional_payload: None,
1534 }),
1535 Action::GoToTab { index: tab_index } => Ok(ProtobufAction {
1536 name: ProtobufActionName::GoToTab as i32,
1537 optional_payload: Some(OptionalPayload::GoToTabPayload(tab_index)),
1538 }),
1539 Action::GoToTabName {
1540 name: tab_name,
1541 create,
1542 } => Ok(ProtobufAction {
1543 name: ProtobufActionName::GoToTabName as i32,
1544 optional_payload: Some(OptionalPayload::GoToTabNamePayload(GoToTabNamePayload {
1545 tab_name,
1546 create,
1547 })),
1548 }),
1549 Action::ToggleTab => Ok(ProtobufAction {
1550 name: ProtobufActionName::ToggleTab as i32,
1551 optional_payload: None,
1552 }),
1553 Action::TabNameInput { input: bytes } => Ok(ProtobufAction {
1554 name: ProtobufActionName::TabNameInput as i32,
1555 optional_payload: Some(OptionalPayload::TabNameInputPayload(bytes)),
1556 }),
1557 Action::UndoRenameTab => Ok(ProtobufAction {
1558 name: ProtobufActionName::UndoRenameTab as i32,
1559 optional_payload: None,
1560 }),
1561 Action::MoveTab { direction } => {
1562 let direction: ProtobufMoveTabDirection = direction.try_into()?;
1563 Ok(ProtobufAction {
1564 name: ProtobufActionName::MoveTab as i32,
1565 optional_payload: Some(OptionalPayload::MoveTabPayload(direction as i32)),
1566 })
1567 },
1568 Action::Run {
1569 command: run_command_action,
1570 near_current_pane: _,
1571 } => {
1572 let run_command_action: ProtobufRunCommandAction = run_command_action.try_into()?;
1573 Ok(ProtobufAction {
1574 name: ProtobufActionName::Run as i32,
1575 optional_payload: Some(OptionalPayload::RunPayload(run_command_action)),
1576 })
1577 },
1578 Action::Detach => Ok(ProtobufAction {
1579 name: ProtobufActionName::Detach as i32,
1580 optional_payload: None,
1581 }),
1582 Action::SetDarkTheme => Ok(ProtobufAction {
1583 name: ProtobufActionName::SetDarkTheme as i32,
1584 optional_payload: None,
1585 }),
1586 Action::SetLightTheme => Ok(ProtobufAction {
1587 name: ProtobufActionName::SetLightTheme as i32,
1588 optional_payload: None,
1589 }),
1590 Action::ToggleTheme => Ok(ProtobufAction {
1591 name: ProtobufActionName::ToggleTheme as i32,
1592 optional_payload: None,
1593 }),
1594 Action::LaunchOrFocusPlugin {
1595 plugin: run_plugin_or_alias,
1596 should_float,
1597 move_to_focused_tab,
1598 should_open_in_place,
1599 close_replaced_pane: _close_replaced_pane,
1600 skip_cache: skip_plugin_cache,
1601 ..
1602 } => {
1603 let configuration = run_plugin_or_alias.get_configuration().unwrap_or_default();
1604 Ok(ProtobufAction {
1605 name: ProtobufActionName::LaunchOrFocusPlugin as i32,
1606 optional_payload: Some(OptionalPayload::LaunchOrFocusPluginPayload(
1607 LaunchOrFocusPluginPayload {
1608 plugin_url: run_plugin_or_alias.location_string(),
1609 should_float,
1610 move_to_focused_tab,
1611 should_open_in_place,
1612 plugin_configuration: Some(configuration.try_into()?),
1613 skip_plugin_cache,
1614 },
1615 )),
1616 })
1617 },
1618 Action::LaunchPlugin {
1619 plugin: run_plugin_or_alias,
1620 should_float,
1621 should_open_in_place,
1622 close_replaced_pane: _close_replaced_pane,
1623 skip_cache: skip_plugin_cache,
1624 cwd: _cwd,
1625 ..
1626 } => {
1627 let configuration = run_plugin_or_alias.get_configuration().unwrap_or_default();
1628 Ok(ProtobufAction {
1629 name: ProtobufActionName::LaunchPlugin as i32,
1630 optional_payload: Some(OptionalPayload::LaunchOrFocusPluginPayload(
1631 LaunchOrFocusPluginPayload {
1632 plugin_url: run_plugin_or_alias.location_string(),
1633 should_float,
1634 move_to_focused_tab: false,
1635 should_open_in_place,
1636 plugin_configuration: Some(configuration.try_into()?),
1637 skip_plugin_cache,
1638 },
1639 )),
1640 })
1641 },
1642 Action::MouseEvent { event } => {
1643 let payload: ProtobufMouseEventPayload = event.try_into()?;
1644 Ok(ProtobufAction {
1645 name: ProtobufActionName::MouseEvent as i32,
1646 optional_payload: Some(OptionalPayload::MouseEventPayload(payload)),
1647 })
1648 },
1649 Action::SearchInput { input: bytes } => Ok(ProtobufAction {
1650 name: ProtobufActionName::SearchInput as i32,
1651 optional_payload: Some(OptionalPayload::SearchInputPayload(bytes)),
1652 }),
1653 Action::Search {
1654 direction: search_direction,
1655 } => {
1656 let search_direction: ProtobufSearchDirection = search_direction.try_into()?;
1657 Ok(ProtobufAction {
1658 name: ProtobufActionName::Search as i32,
1659 optional_payload: Some(OptionalPayload::SearchPayload(search_direction as i32)),
1660 })
1661 },
1662 Action::SearchToggleOption {
1663 option: search_option,
1664 } => {
1665 let search_option: ProtobufSearchOption = search_option.try_into()?;
1666 Ok(ProtobufAction {
1667 name: ProtobufActionName::SearchToggleOption as i32,
1668 optional_payload: Some(OptionalPayload::SearchToggleOptionPayload(
1669 search_option as i32,
1670 )),
1671 })
1672 },
1673 Action::ToggleMouseMode => Ok(ProtobufAction {
1674 name: ProtobufActionName::ToggleMouseMode as i32,
1675 optional_payload: None,
1676 }),
1677 Action::PreviousSwapLayout => Ok(ProtobufAction {
1678 name: ProtobufActionName::PreviousSwapLayout as i32,
1679 optional_payload: None,
1680 }),
1681 Action::NextSwapLayout => Ok(ProtobufAction {
1682 name: ProtobufActionName::NextSwapLayout as i32,
1683 optional_payload: None,
1684 }),
1685 Action::OverrideLayout {
1686 tabs,
1687 retain_existing_terminal_panes,
1688 retain_existing_plugin_panes,
1689 apply_only_to_active_tab,
1690 } => Ok(ProtobufAction {
1691 name: ProtobufActionName::OverrideLayout as i32,
1692 optional_payload: Some(OptionalPayload::OverrideLayoutPayload(
1693 OverrideLayoutPayload {
1694 tabs: tabs
1695 .into_iter()
1696 .map(|t| t.try_into())
1697 .collect::<Result<Vec<_>, _>>()?,
1698 retain_existing_terminal_panes,
1699 retain_existing_plugin_panes,
1700 apply_only_to_active_tab,
1701 },
1702 )),
1703 }),
1704 Action::QueryTabNames => Ok(ProtobufAction {
1705 name: ProtobufActionName::QueryTabNames as i32,
1706 optional_payload: None,
1707 }),
1708 Action::NewTiledPluginPane {
1709 plugin: run_plugin,
1710 pane_name,
1711 skip_cache: skip_plugin_cache,
1712 cwd: _cwd,
1713 ..
1714 } => Ok(ProtobufAction {
1715 name: ProtobufActionName::NewTiledPluginPane as i32,
1716 optional_payload: Some(OptionalPayload::NewTiledPluginPanePayload(
1717 NewPluginPanePayload {
1718 plugin_url: run_plugin.location_string(),
1719 pane_name,
1720 skip_plugin_cache,
1721 },
1722 )),
1723 }),
1724 Action::NewFloatingPluginPane {
1725 plugin: run_plugin,
1726 pane_name,
1727 skip_cache: skip_plugin_cache,
1728 cwd: _cwd,
1729 coordinates: _coordinates,
1730 ..
1731 } => Ok(ProtobufAction {
1732 name: ProtobufActionName::NewFloatingPluginPane as i32,
1733 optional_payload: Some(OptionalPayload::NewFloatingPluginPanePayload(
1734 NewPluginPanePayload {
1735 plugin_url: run_plugin.location_string(),
1736 pane_name,
1737 skip_plugin_cache,
1738 },
1739 )),
1740 }),
1741 Action::StartOrReloadPlugin { plugin: run_plugin } => Ok(ProtobufAction {
1742 name: ProtobufActionName::StartOrReloadPlugin as i32,
1743 optional_payload: Some(OptionalPayload::StartOrReloadPluginPayload(
1744 run_plugin.location_string(),
1745 )),
1746 }),
1747 Action::CloseTerminalPane {
1748 pane_id: terminal_pane_id,
1749 } => Ok(ProtobufAction {
1750 name: ProtobufActionName::CloseTerminalPane as i32,
1751 optional_payload: Some(OptionalPayload::CloseTerminalPanePayload(terminal_pane_id)),
1752 }),
1753 Action::ClosePluginPane {
1754 pane_id: plugin_pane_id,
1755 } => Ok(ProtobufAction {
1756 name: ProtobufActionName::ClosePluginPane as i32,
1757 optional_payload: Some(OptionalPayload::ClosePluginPanePayload(plugin_pane_id)),
1758 }),
1759 Action::FocusTerminalPaneWithId {
1760 pane_id: terminal_pane_id,
1761 should_float_if_hidden,
1762 should_be_in_place_if_hidden,
1763 } => Ok(ProtobufAction {
1764 name: ProtobufActionName::FocusTerminalPaneWithId as i32,
1765 optional_payload: Some(OptionalPayload::FocusTerminalPaneWithIdPayload(
1766 PaneIdAndShouldFloat {
1767 pane_id: terminal_pane_id,
1768 should_float: should_float_if_hidden,
1769 should_be_in_place: should_be_in_place_if_hidden,
1770 },
1771 )),
1772 }),
1773 Action::FocusPluginPaneWithId {
1774 pane_id: plugin_pane_id,
1775 should_float_if_hidden,
1776 should_be_in_place_if_hidden,
1777 } => Ok(ProtobufAction {
1778 name: ProtobufActionName::FocusPluginPaneWithId as i32,
1779 optional_payload: Some(OptionalPayload::FocusPluginPaneWithIdPayload(
1780 PaneIdAndShouldFloat {
1781 pane_id: plugin_pane_id,
1782 should_float: should_float_if_hidden,
1783 should_be_in_place: should_be_in_place_if_hidden,
1784 },
1785 )),
1786 }),
1787 Action::RenameTerminalPane {
1788 pane_id: terminal_pane_id,
1789 name: new_name,
1790 } => Ok(ProtobufAction {
1791 name: ProtobufActionName::RenameTerminalPane as i32,
1792 optional_payload: Some(OptionalPayload::RenameTerminalPanePayload(IdAndName {
1793 name: new_name,
1794 id: terminal_pane_id,
1795 })),
1796 }),
1797 Action::RenamePluginPane {
1798 pane_id: plugin_pane_id,
1799 name: new_name,
1800 } => Ok(ProtobufAction {
1801 name: ProtobufActionName::RenamePluginPane as i32,
1802 optional_payload: Some(OptionalPayload::RenamePluginPanePayload(IdAndName {
1803 name: new_name,
1804 id: plugin_pane_id,
1805 })),
1806 }),
1807 Action::RenameTab {
1808 tab_index,
1809 name: new_name,
1810 } => Ok(ProtobufAction {
1811 name: ProtobufActionName::RenameTab as i32,
1812 optional_payload: Some(OptionalPayload::RenameTabPayload(IdAndName {
1813 name: new_name,
1814 id: tab_index,
1815 })),
1816 }),
1817 Action::BreakPane => Ok(ProtobufAction {
1818 name: ProtobufActionName::BreakPane as i32,
1819 optional_payload: None,
1820 }),
1821 Action::BreakPaneRight => Ok(ProtobufAction {
1822 name: ProtobufActionName::BreakPaneRight as i32,
1823 optional_payload: None,
1824 }),
1825 Action::BreakPaneLeft => Ok(ProtobufAction {
1826 name: ProtobufActionName::BreakPaneLeft as i32,
1827 optional_payload: None,
1828 }),
1829 Action::RenameSession { name: session_name } => Ok(ProtobufAction {
1830 name: ProtobufActionName::RenameSession as i32,
1831 optional_payload: Some(OptionalPayload::RenameSessionPayload(session_name)),
1832 }),
1833 Action::KeybindPipe { .. } => Ok(ProtobufAction {
1834 name: ProtobufActionName::KeybindPipe as i32,
1835 optional_payload: None,
1836 }),
1837 Action::TogglePanePinned { .. } => Ok(ProtobufAction {
1838 name: ProtobufActionName::TogglePanePinned as i32,
1839 optional_payload: None,
1840 }),
1841 Action::TogglePaneInGroup { .. } => Ok(ProtobufAction {
1842 name: ProtobufActionName::TogglePaneInGroup as i32,
1843 optional_payload: None,
1844 }),
1845 Action::ToggleGroupMarking { .. } => Ok(ProtobufAction {
1846 name: ProtobufActionName::ToggleGroupMarking as i32,
1847 optional_payload: None,
1848 }),
1849 Action::NewStackedPane {
1850 command: _,
1851 pane_name: _,
1852 near_current_pane: _,
1853 ..
1854 } => Ok(ProtobufAction {
1855 name: ProtobufActionName::NewStackedPane as i32,
1856 optional_payload: None,
1857 }),
1858 Action::NewBlockingPane {
1859 placement,
1860 pane_name,
1861 command,
1862 unblock_condition,
1863 near_current_pane,
1864 ..
1865 } => {
1866 let placement: ProtobufNewPanePlacement = placement.try_into()?;
1867 let command = command.and_then(|c| {
1868 let protobuf_command: ProtobufRunCommandAction = c.try_into().ok()?;
1869 Some(protobuf_command)
1870 });
1871 let unblock_condition = unblock_condition
1872 .map(|uc| {
1873 let protobuf_uc: ProtobufUnblockCondition = uc.try_into().ok()?;
1874 Some(protobuf_uc as i32)
1875 })
1876 .flatten();
1877 Ok(ProtobufAction {
1878 name: ProtobufActionName::NewBlockingPane as i32,
1879 optional_payload: Some(OptionalPayload::NewBlockingPanePayload(
1880 NewBlockingPanePayload {
1881 placement: Some(placement),
1882 pane_name,
1883 command,
1884 unblock_condition,
1885 near_current_pane,
1886 },
1887 )),
1888 })
1889 },
1890 Action::NewInPlacePane {
1891 command: run_command_action,
1892 pane_name,
1893 near_current_pane,
1894 pane_id_to_replace,
1895 close_replaced_pane,
1896 ..
1897 } => {
1898 let command = run_command_action.and_then(|r| {
1899 let mut protobuf_run_command_action: ProtobufRunCommandAction =
1900 r.try_into().ok()?;
1901 let pane_name = pane_name.and_then(|n| n.try_into().ok());
1902 protobuf_run_command_action.pane_name = pane_name;
1903 Some(protobuf_run_command_action)
1904 });
1905 let pane_id_to_replace = pane_id_to_replace.and_then(|p| p.try_into().ok());
1906 Ok(ProtobufAction {
1907 name: ProtobufActionName::NewInPlacePane as i32,
1908 optional_payload: Some(OptionalPayload::NewInPlacePanePayload(
1909 NewInPlacePanePayload {
1910 command,
1911 pane_name: None, near_current_pane,
1913 pane_id_to_replace,
1914 close_replace_pane: close_replaced_pane,
1915 },
1916 )),
1917 })
1918 },
1919 Action::NoOp
1920 | Action::Confirm
1921 | Action::NewInPlacePluginPane {
1922 plugin: _,
1923 pane_name: _,
1924 skip_cache: _,
1925 close_replaced_pane: _,
1926 ..
1927 }
1928 | Action::Deny
1929 | Action::Copy
1930 | Action::DumpLayout
1931 | Action::CliPipe { .. }
1932 | Action::ListClients
1933 | Action::ListPanes { .. }
1934 | Action::StackPanes { pane_ids: _ }
1935 | Action::ChangeFloatingPaneCoordinates {
1936 pane_id: _,
1937 coordinates: _,
1938 }
1939 | Action::TogglePaneBorderless { pane_id: _ }
1940 | Action::SetPaneBorderless { .. }
1941 | Action::SkipConfirm { action: _ }
1942 | Action::SwitchSession { .. }
1943 | Action::SaveSession
1944 | Action::ListTabs { .. }
1945 | Action::CurrentTabInfo { .. }
1946 | Action::SetPaneColor { .. } => Err("Unsupported action"),
1947 }
1948 }
1949}
1950
1951impl TryFrom<ProtobufSearchOption> for SearchOption {
1952 type Error = &'static str;
1953 fn try_from(protobuf_search_option: ProtobufSearchOption) -> Result<Self, &'static str> {
1954 match protobuf_search_option {
1955 ProtobufSearchOption::CaseSensitivity => Ok(SearchOption::CaseSensitivity),
1956 ProtobufSearchOption::WholeWord => Ok(SearchOption::WholeWord),
1957 ProtobufSearchOption::Wrap => Ok(SearchOption::Wrap),
1958 }
1959 }
1960}
1961
1962impl TryFrom<SearchOption> for ProtobufSearchOption {
1963 type Error = &'static str;
1964 fn try_from(search_option: SearchOption) -> Result<Self, &'static str> {
1965 match search_option {
1966 SearchOption::CaseSensitivity => Ok(ProtobufSearchOption::CaseSensitivity),
1967 SearchOption::WholeWord => Ok(ProtobufSearchOption::WholeWord),
1968 SearchOption::Wrap => Ok(ProtobufSearchOption::Wrap),
1969 }
1970 }
1971}
1972
1973impl TryFrom<ProtobufSearchDirection> for SearchDirection {
1974 type Error = &'static str;
1975 fn try_from(protobuf_search_direction: ProtobufSearchDirection) -> Result<Self, &'static str> {
1976 match protobuf_search_direction {
1977 ProtobufSearchDirection::Up => Ok(SearchDirection::Up),
1978 ProtobufSearchDirection::Down => Ok(SearchDirection::Down),
1979 }
1980 }
1981}
1982
1983impl TryFrom<SearchDirection> for ProtobufSearchDirection {
1984 type Error = &'static str;
1985 fn try_from(search_direction: SearchDirection) -> Result<Self, &'static str> {
1986 match search_direction {
1987 SearchDirection::Up => Ok(ProtobufSearchDirection::Up),
1988 SearchDirection::Down => Ok(ProtobufSearchDirection::Down),
1989 }
1990 }
1991}
1992
1993impl TryFrom<ProtobufMoveTabDirection> for Direction {
1994 type Error = &'static str;
1995 fn try_from(
1996 protobuf_move_tab_direction: ProtobufMoveTabDirection,
1997 ) -> Result<Self, &'static str> {
1998 match protobuf_move_tab_direction {
1999 ProtobufMoveTabDirection::Left => Ok(Direction::Left),
2000 ProtobufMoveTabDirection::Right => Ok(Direction::Right),
2001 }
2002 }
2003}
2004
2005impl TryFrom<Direction> for ProtobufMoveTabDirection {
2006 type Error = &'static str;
2007 fn try_from(direction: Direction) -> Result<Self, &'static str> {
2008 match direction {
2009 Direction::Left => Ok(ProtobufMoveTabDirection::Left),
2010 Direction::Right => Ok(ProtobufMoveTabDirection::Right),
2011 _ => Err("Wrong direction for ProtobufMoveTabDirection"),
2012 }
2013 }
2014}
2015
2016impl TryFrom<ProtobufRunCommandAction> for RunCommandAction {
2017 type Error = &'static str;
2018 fn try_from(
2019 protobuf_run_command_action: ProtobufRunCommandAction,
2020 ) -> Result<Self, &'static str> {
2021 let command = PathBuf::from(protobuf_run_command_action.command);
2022 let args: Vec<String> = protobuf_run_command_action.args;
2023 let cwd: Option<PathBuf> = protobuf_run_command_action.cwd.map(|c| PathBuf::from(c));
2024 let direction: Option<Direction> = protobuf_run_command_action
2025 .direction
2026 .and_then(|d| ProtobufResizeDirection::from_i32(d))
2027 .and_then(|d| d.try_into().ok());
2028 let hold_on_close = protobuf_run_command_action.hold_on_close;
2029 let hold_on_start = protobuf_run_command_action.hold_on_start;
2030 Ok(RunCommandAction {
2031 command,
2032 args,
2033 cwd,
2034 direction,
2035 hold_on_close,
2036 hold_on_start,
2037 ..Default::default()
2038 })
2039 }
2040}
2041
2042impl TryFrom<RunCommandAction> for ProtobufRunCommandAction {
2043 type Error = &'static str;
2044 fn try_from(run_command_action: RunCommandAction) -> Result<Self, &'static str> {
2045 let command = run_command_action.command.display().to_string();
2046 let args: Vec<String> = run_command_action.args;
2047 let cwd = run_command_action.cwd.map(|c| c.display().to_string());
2048 let direction = run_command_action.direction.and_then(|p| {
2049 let direction: ProtobufResizeDirection = p.try_into().ok()?;
2050 Some(direction as i32)
2051 });
2052 let hold_on_close = run_command_action.hold_on_close;
2053 let hold_on_start = run_command_action.hold_on_start;
2054 Ok(ProtobufRunCommandAction {
2055 command,
2056 args,
2057 cwd,
2058 direction,
2059 hold_on_close,
2060 hold_on_start,
2061 pane_name: None,
2062 })
2063 }
2064}
2065
2066impl TryFrom<ProtobufPosition> for Position {
2067 type Error = &'static str;
2068 fn try_from(protobuf_position: ProtobufPosition) -> Result<Self, &'static str> {
2069 Ok(Position::new(
2070 protobuf_position.line as i32,
2071 protobuf_position.column as u16,
2072 ))
2073 }
2074}
2075
2076impl TryFrom<Position> for ProtobufPosition {
2077 type Error = &'static str;
2078 fn try_from(position: Position) -> Result<Self, &'static str> {
2079 Ok(ProtobufPosition {
2080 line: position.line.0 as i64,
2081 column: position.column.0 as i64,
2082 })
2083 }
2084}
2085
2086impl TryFrom<ProtobufMouseEventPayload> for MouseEvent {
2087 type Error = &'static str;
2088 fn try_from(protobuf_event: ProtobufMouseEventPayload) -> Result<Self, &'static str> {
2089 Ok(MouseEvent {
2090 event_type: match protobuf_event.event_type as u32 {
2091 0 => MouseEventType::Press,
2092 1 => MouseEventType::Release,
2093 _ => MouseEventType::Motion,
2094 },
2095 left: protobuf_event.left as bool,
2096 right: protobuf_event.right as bool,
2097 middle: protobuf_event.middle as bool,
2098 wheel_up: protobuf_event.wheel_up as bool,
2099 wheel_down: protobuf_event.wheel_down as bool,
2100 shift: protobuf_event.shift as bool,
2101 alt: protobuf_event.alt as bool,
2102 ctrl: protobuf_event.ctrl as bool,
2103 position: Position::new(protobuf_event.line as i32, protobuf_event.column as u16),
2104 })
2105 }
2106}
2107
2108impl TryFrom<MouseEvent> for ProtobufMouseEventPayload {
2109 type Error = &'static str;
2110 fn try_from(event: MouseEvent) -> Result<Self, &'static str> {
2111 Ok(ProtobufMouseEventPayload {
2112 event_type: match event.event_type {
2113 MouseEventType::Press => 0,
2114 MouseEventType::Release => 1,
2115 MouseEventType::Motion => 2,
2116 } as u32,
2117 left: event.left as bool,
2118 right: event.right as bool,
2119 middle: event.middle as bool,
2120 wheel_up: event.wheel_up as bool,
2121 wheel_down: event.wheel_down as bool,
2122 shift: event.shift as bool,
2123 alt: event.alt as bool,
2124 ctrl: event.ctrl as bool,
2125 line: event.position.line.0 as i64,
2126 column: event.position.column.0 as i64,
2127 })
2128 }
2129}
2130
2131impl TryFrom<ProtobufPluginConfiguration> for PluginUserConfiguration {
2132 type Error = &'static str;
2133 fn try_from(plugin_configuration: ProtobufPluginConfiguration) -> Result<Self, &'static str> {
2134 let mut converted = BTreeMap::new();
2135 for name_and_value in plugin_configuration.name_and_value {
2136 converted.insert(name_and_value.name, name_and_value.value);
2137 }
2138 Ok(PluginUserConfiguration::new(converted))
2139 }
2140}
2141
2142impl TryFrom<PluginUserConfiguration> for ProtobufPluginConfiguration {
2143 type Error = &'static str;
2144 fn try_from(plugin_configuration: PluginUserConfiguration) -> Result<Self, &'static str> {
2145 let mut converted = vec![];
2146 for (name, value) in plugin_configuration.inner() {
2147 let name_and_value = ProtobufNameAndValue {
2148 name: name.to_owned(),
2149 value: value.to_owned(),
2150 };
2151 converted.push(name_and_value);
2152 }
2153 Ok(ProtobufPluginConfiguration {
2154 name_and_value: converted,
2155 })
2156 }
2157}
2158
2159impl TryFrom<&ProtobufPluginConfiguration> for BTreeMap<String, String> {
2160 type Error = &'static str;
2161 fn try_from(plugin_configuration: &ProtobufPluginConfiguration) -> Result<Self, &'static str> {
2162 let mut converted = BTreeMap::new();
2163 for name_and_value in &plugin_configuration.name_and_value {
2164 converted.insert(
2165 name_and_value.name.to_owned(),
2166 name_and_value.value.to_owned(),
2167 );
2168 }
2169 Ok(converted)
2170 }
2171}
2172
2173impl TryFrom<ProtobufKeyWithModifier> for KeyWithModifier {
2174 type Error = &'static str;
2175 fn try_from(protobuf_key: ProtobufKeyWithModifier) -> Result<Self, &'static str> {
2176 let bare_key = match ProtobufBareKey::from_i32(protobuf_key.bare_key) {
2177 Some(ProtobufBareKey::PageDown) => crate::data::BareKey::PageDown,
2178 Some(ProtobufBareKey::PageUp) => crate::data::BareKey::PageUp,
2179 Some(ProtobufBareKey::Left) => crate::data::BareKey::Left,
2180 Some(ProtobufBareKey::Down) => crate::data::BareKey::Down,
2181 Some(ProtobufBareKey::Up) => crate::data::BareKey::Up,
2182 Some(ProtobufBareKey::Right) => crate::data::BareKey::Right,
2183 Some(ProtobufBareKey::Home) => crate::data::BareKey::Home,
2184 Some(ProtobufBareKey::End) => crate::data::BareKey::End,
2185 Some(ProtobufBareKey::Backspace) => crate::data::BareKey::Backspace,
2186 Some(ProtobufBareKey::Delete) => crate::data::BareKey::Delete,
2187 Some(ProtobufBareKey::Insert) => crate::data::BareKey::Insert,
2188 Some(ProtobufBareKey::F1) => crate::data::BareKey::F(1),
2189 Some(ProtobufBareKey::F2) => crate::data::BareKey::F(2),
2190 Some(ProtobufBareKey::F3) => crate::data::BareKey::F(3),
2191 Some(ProtobufBareKey::F4) => crate::data::BareKey::F(4),
2192 Some(ProtobufBareKey::F5) => crate::data::BareKey::F(5),
2193 Some(ProtobufBareKey::F6) => crate::data::BareKey::F(6),
2194 Some(ProtobufBareKey::F7) => crate::data::BareKey::F(7),
2195 Some(ProtobufBareKey::F8) => crate::data::BareKey::F(8),
2196 Some(ProtobufBareKey::F9) => crate::data::BareKey::F(9),
2197 Some(ProtobufBareKey::F10) => crate::data::BareKey::F(10),
2198 Some(ProtobufBareKey::F11) => crate::data::BareKey::F(11),
2199 Some(ProtobufBareKey::F12) => crate::data::BareKey::F(12),
2200 Some(ProtobufBareKey::Char) => {
2201 if let Some(character) = protobuf_key.character {
2202 let ch = character
2203 .chars()
2204 .next()
2205 .ok_or("BareKey::Char requires a character")?;
2206 crate::data::BareKey::Char(ch)
2207 } else {
2208 return Err("BareKey::Char requires a character");
2209 }
2210 },
2211 Some(ProtobufBareKey::Tab) => crate::data::BareKey::Tab,
2212 Some(ProtobufBareKey::Esc) => crate::data::BareKey::Esc,
2213 Some(ProtobufBareKey::Enter) => crate::data::BareKey::Enter,
2214 Some(ProtobufBareKey::CapsLock) => crate::data::BareKey::CapsLock,
2215 Some(ProtobufBareKey::ScrollLock) => crate::data::BareKey::ScrollLock,
2216 Some(ProtobufBareKey::NumLock) => crate::data::BareKey::NumLock,
2217 Some(ProtobufBareKey::PrintScreen) => crate::data::BareKey::PrintScreen,
2218 Some(ProtobufBareKey::Pause) => crate::data::BareKey::Pause,
2219 Some(ProtobufBareKey::Menu) => crate::data::BareKey::Menu,
2220 _ => return Err("Unknown BareKey"),
2221 };
2222
2223 let mut key_modifiers = std::collections::BTreeSet::new();
2224 for modifier in protobuf_key.key_modifiers {
2225 let key_modifier = match ProtobufKeyModifier::from_i32(modifier) {
2226 Some(ProtobufKeyModifier::Ctrl) => crate::data::KeyModifier::Ctrl,
2227 Some(ProtobufKeyModifier::Alt) => crate::data::KeyModifier::Alt,
2228 Some(ProtobufKeyModifier::Shift) => crate::data::KeyModifier::Shift,
2229 Some(ProtobufKeyModifier::Super) => crate::data::KeyModifier::Super,
2230 _ => continue,
2231 };
2232 key_modifiers.insert(key_modifier);
2233 }
2234
2235 Ok(KeyWithModifier {
2236 bare_key,
2237 key_modifiers,
2238 })
2239 }
2240}
2241
2242impl TryFrom<KeyWithModifier> for ProtobufKeyWithModifier {
2243 type Error = &'static str;
2244 fn try_from(key: KeyWithModifier) -> Result<Self, &'static str> {
2245 let (bare_key, character) = match key.bare_key {
2246 crate::data::BareKey::PageDown => (ProtobufBareKey::PageDown as i32, None),
2247 crate::data::BareKey::PageUp => (ProtobufBareKey::PageUp as i32, None),
2248 crate::data::BareKey::Left => (ProtobufBareKey::Left as i32, None),
2249 crate::data::BareKey::Down => (ProtobufBareKey::Down as i32, None),
2250 crate::data::BareKey::Up => (ProtobufBareKey::Up as i32, None),
2251 crate::data::BareKey::Right => (ProtobufBareKey::Right as i32, None),
2252 crate::data::BareKey::Home => (ProtobufBareKey::Home as i32, None),
2253 crate::data::BareKey::End => (ProtobufBareKey::End as i32, None),
2254 crate::data::BareKey::Backspace => (ProtobufBareKey::Backspace as i32, None),
2255 crate::data::BareKey::Delete => (ProtobufBareKey::Delete as i32, None),
2256 crate::data::BareKey::Insert => (ProtobufBareKey::Insert as i32, None),
2257 crate::data::BareKey::F(1) => (ProtobufBareKey::F1 as i32, None),
2258 crate::data::BareKey::F(2) => (ProtobufBareKey::F2 as i32, None),
2259 crate::data::BareKey::F(3) => (ProtobufBareKey::F3 as i32, None),
2260 crate::data::BareKey::F(4) => (ProtobufBareKey::F4 as i32, None),
2261 crate::data::BareKey::F(5) => (ProtobufBareKey::F5 as i32, None),
2262 crate::data::BareKey::F(6) => (ProtobufBareKey::F6 as i32, None),
2263 crate::data::BareKey::F(7) => (ProtobufBareKey::F7 as i32, None),
2264 crate::data::BareKey::F(8) => (ProtobufBareKey::F8 as i32, None),
2265 crate::data::BareKey::F(9) => (ProtobufBareKey::F9 as i32, None),
2266 crate::data::BareKey::F(10) => (ProtobufBareKey::F10 as i32, None),
2267 crate::data::BareKey::F(11) => (ProtobufBareKey::F11 as i32, None),
2268 crate::data::BareKey::F(12) => (ProtobufBareKey::F12 as i32, None),
2269 crate::data::BareKey::Char(c) => (ProtobufBareKey::Char as i32, Some(c.to_string())),
2270 crate::data::BareKey::Tab => (ProtobufBareKey::Tab as i32, None),
2271 crate::data::BareKey::Esc => (ProtobufBareKey::Esc as i32, None),
2272 crate::data::BareKey::Enter => (ProtobufBareKey::Enter as i32, None),
2273 crate::data::BareKey::CapsLock => (ProtobufBareKey::CapsLock as i32, None),
2274 crate::data::BareKey::ScrollLock => (ProtobufBareKey::ScrollLock as i32, None),
2275 crate::data::BareKey::NumLock => (ProtobufBareKey::NumLock as i32, None),
2276 crate::data::BareKey::PrintScreen => (ProtobufBareKey::PrintScreen as i32, None),
2277 crate::data::BareKey::Pause => (ProtobufBareKey::Pause as i32, None),
2278 crate::data::BareKey::Menu => (ProtobufBareKey::Menu as i32, None),
2279 _ => return Err("Unsupported BareKey"),
2280 };
2281
2282 let key_modifiers: Vec<i32> = key
2283 .key_modifiers
2284 .iter()
2285 .map(|m| match m {
2286 crate::data::KeyModifier::Ctrl => ProtobufKeyModifier::Ctrl as i32,
2287 crate::data::KeyModifier::Alt => ProtobufKeyModifier::Alt as i32,
2288 crate::data::KeyModifier::Shift => ProtobufKeyModifier::Shift as i32,
2289 crate::data::KeyModifier::Super => ProtobufKeyModifier::Super as i32,
2290 })
2291 .collect();
2292
2293 Ok(ProtobufKeyWithModifier {
2294 bare_key,
2295 key_modifiers,
2296 character,
2297 })
2298 }
2299}
2300
2301impl TryFrom<ProtobufUnblockCondition> for UnblockCondition {
2303 type Error = &'static str;
2304 fn try_from(protobuf_uc: ProtobufUnblockCondition) -> Result<Self, &'static str> {
2305 match protobuf_uc {
2306 ProtobufUnblockCondition::UnblockOnExitSuccess => Ok(UnblockCondition::OnExitSuccess),
2307 ProtobufUnblockCondition::UnblockOnExitFailure => Ok(UnblockCondition::OnExitFailure),
2308 ProtobufUnblockCondition::UnblockOnAnyExit => Ok(UnblockCondition::OnAnyExit),
2309 }
2310 }
2311}
2312
2313impl TryFrom<UnblockCondition> for ProtobufUnblockCondition {
2314 type Error = &'static str;
2315 fn try_from(uc: UnblockCondition) -> Result<Self, &'static str> {
2316 match uc {
2317 UnblockCondition::OnExitSuccess => Ok(ProtobufUnblockCondition::UnblockOnExitSuccess),
2318 UnblockCondition::OnExitFailure => Ok(ProtobufUnblockCondition::UnblockOnExitFailure),
2319 UnblockCondition::OnAnyExit => Ok(ProtobufUnblockCondition::UnblockOnAnyExit),
2320 }
2321 }
2322}
2323
2324impl TryFrom<i32> for UnblockCondition {
2325 type Error = &'static str;
2326 fn try_from(value: i32) -> Result<Self, &'static str> {
2327 match ProtobufUnblockCondition::from_i32(value) {
2328 Some(uc) => uc.try_into(),
2329 None => Err("Invalid UnblockCondition value"),
2330 }
2331 }
2332}
2333
2334impl TryFrom<ProtobufPaneId> for PaneId {
2336 type Error = &'static str;
2337 fn try_from(protobuf_pane_id: ProtobufPaneId) -> Result<Self, &'static str> {
2338 use super::generated_api::api::action::pane_id::PaneIdVariant;
2339
2340 match protobuf_pane_id.pane_id_variant {
2341 Some(PaneIdVariant::Terminal(id)) => Ok(PaneId::Terminal(id)),
2342 Some(PaneIdVariant::Plugin(id)) => Ok(PaneId::Plugin(id)),
2343 None => Err("PaneId must have either terminal or plugin id"),
2344 }
2345 }
2346}
2347
2348impl TryFrom<PaneId> for ProtobufPaneId {
2349 type Error = &'static str;
2350 fn try_from(pane_id: PaneId) -> Result<Self, &'static str> {
2351 use super::generated_api::api::action::pane_id::PaneIdVariant;
2352
2353 let pane_id_variant = match pane_id {
2354 PaneId::Terminal(id) => Some(PaneIdVariant::Terminal(id)),
2355 PaneId::Plugin(id) => Some(PaneIdVariant::Plugin(id)),
2356 };
2357 Ok(ProtobufPaneId { pane_id_variant })
2358 }
2359}
2360
2361impl TryFrom<ProtobufSplitSize> for SplitSize {
2363 type Error = &'static str;
2364 fn try_from(protobuf_split_size: ProtobufSplitSize) -> Result<Self, &'static str> {
2365 use super::generated_api::api::action::split_size::SplitSizeVariant;
2366
2367 match protobuf_split_size.split_size_variant {
2368 Some(SplitSizeVariant::Percent(p)) => Ok(SplitSize::Percent(p as usize)),
2369 Some(SplitSizeVariant::Fixed(f)) => Ok(SplitSize::Fixed(f as usize)),
2370 None => Err("SplitSize must have either percent or fixed value"),
2371 }
2372 }
2373}
2374
2375impl TryFrom<SplitSize> for ProtobufSplitSize {
2376 type Error = &'static str;
2377 fn try_from(split_size: SplitSize) -> Result<Self, &'static str> {
2378 use super::generated_api::api::action::split_size::SplitSizeVariant;
2379
2380 let split_size_variant = match split_size {
2381 SplitSize::Percent(p) => Some(SplitSizeVariant::Percent(p as u32)),
2382 SplitSize::Fixed(f) => Some(SplitSizeVariant::Fixed(f as u32)),
2383 };
2384 Ok(ProtobufSplitSize { split_size_variant })
2385 }
2386}
2387
2388impl TryFrom<ProtobufSplitSize> for PercentOrFixed {
2389 type Error = &'static str;
2390 fn try_from(protobuf_split_size: ProtobufSplitSize) -> Result<Self, &'static str> {
2391 use super::generated_api::api::action::split_size::SplitSizeVariant;
2392
2393 match protobuf_split_size.split_size_variant {
2394 Some(SplitSizeVariant::Percent(p)) => Ok(PercentOrFixed::Percent(p as usize)),
2395 Some(SplitSizeVariant::Fixed(f)) => Ok(PercentOrFixed::Fixed(f as usize)),
2396 None => Err("PercentOrFixed must have either percent or fixed value"),
2397 }
2398 }
2399}
2400
2401impl TryFrom<PercentOrFixed> for ProtobufSplitSize {
2402 type Error = &'static str;
2403 fn try_from(percent_or_fixed: PercentOrFixed) -> Result<Self, &'static str> {
2404 use super::generated_api::api::action::split_size::SplitSizeVariant;
2405
2406 let split_size_variant = match percent_or_fixed {
2407 PercentOrFixed::Percent(p) => Some(SplitSizeVariant::Percent(p as u32)),
2408 PercentOrFixed::Fixed(f) => Some(SplitSizeVariant::Fixed(f as u32)),
2409 };
2410 Ok(ProtobufSplitSize { split_size_variant })
2411 }
2412}
2413
2414impl TryFrom<ProtobufFloatingPaneCoordinates> for FloatingPaneCoordinates {
2416 type Error = &'static str;
2417 fn try_from(protobuf_coords: ProtobufFloatingPaneCoordinates) -> Result<Self, &'static str> {
2418 Ok(FloatingPaneCoordinates {
2419 x: protobuf_coords.x.and_then(|x| x.try_into().ok()),
2420 y: protobuf_coords.y.and_then(|y| y.try_into().ok()),
2421 width: protobuf_coords.width.and_then(|w| w.try_into().ok()),
2422 height: protobuf_coords.height.and_then(|h| h.try_into().ok()),
2423 pinned: protobuf_coords.pinned,
2424 borderless: protobuf_coords.borderless,
2425 })
2426 }
2427}
2428
2429impl TryFrom<FloatingPaneCoordinates> for ProtobufFloatingPaneCoordinates {
2430 type Error = &'static str;
2431 fn try_from(coords: FloatingPaneCoordinates) -> Result<Self, &'static str> {
2432 Ok(ProtobufFloatingPaneCoordinates {
2433 x: coords.x.and_then(|x| x.try_into().ok()),
2434 y: coords.y.and_then(|y| y.try_into().ok()),
2435 width: coords.width.and_then(|w| w.try_into().ok()),
2436 height: coords.height.and_then(|h| h.try_into().ok()),
2437 pinned: coords.pinned,
2438 borderless: coords.borderless,
2439 })
2440 }
2441}
2442
2443impl TryFrom<ProtobufNewPanePlacement> for NewPanePlacement {
2445 type Error = &'static str;
2446 fn try_from(protobuf_placement: ProtobufNewPanePlacement) -> Result<Self, &'static str> {
2447 use super::generated_api::api::action::new_pane_placement::PlacementVariant;
2448
2449 match protobuf_placement.placement_variant {
2450 Some(PlacementVariant::NoPreference(opts)) => Ok(NewPanePlacement::NoPreference {
2451 borderless: opts.borderless,
2452 }),
2453 Some(PlacementVariant::Tiled(tiled)) => {
2454 let direction = tiled
2455 .direction
2456 .and_then(|d| ProtobufResizeDirection::from_i32(d))
2457 .and_then(|d| d.try_into().ok());
2458 Ok(NewPanePlacement::Tiled {
2459 direction,
2460 borderless: tiled.borderless,
2461 })
2462 },
2463 Some(PlacementVariant::Floating(floating)) => {
2464 let coords = floating.coordinates.and_then(|c| c.try_into().ok());
2465 Ok(NewPanePlacement::Floating(coords))
2466 },
2467 Some(PlacementVariant::InPlace(config)) => {
2468 let pane_id_to_replace =
2469 config.pane_id_to_replace.and_then(|id| id.try_into().ok());
2470 Ok(NewPanePlacement::InPlace {
2471 pane_id_to_replace,
2472 close_replaced_pane: config.close_replaced_pane,
2473 borderless: config.borderless,
2474 })
2475 },
2476 Some(PlacementVariant::Stacked(stacked)) => {
2477 let pane_id = stacked.pane_id.and_then(|id| id.try_into().ok());
2478 Ok(NewPanePlacement::Stacked {
2479 pane_id_to_stack_under: pane_id,
2480 borderless: stacked.borderless,
2481 })
2482 },
2483 None => Err("NewPanePlacement must have a placement variant"),
2484 }
2485 }
2486}
2487
2488impl TryFrom<NewPanePlacement> for ProtobufNewPanePlacement {
2489 type Error = &'static str;
2490 fn try_from(placement: NewPanePlacement) -> Result<Self, &'static str> {
2491 use super::generated_api::api::action::new_pane_placement::PlacementVariant;
2492 use super::generated_api::api::action::NoPreferenceOptions;
2493
2494 let placement_variant = match placement {
2495 NewPanePlacement::NoPreference { borderless } => {
2496 Some(PlacementVariant::NoPreference(NoPreferenceOptions {
2497 borderless,
2498 }))
2499 },
2500 NewPanePlacement::Tiled {
2501 direction,
2502 borderless,
2503 } => {
2504 let direction = direction.and_then(|d| {
2505 let protobuf_direction: ProtobufResizeDirection = d.try_into().ok()?;
2506 Some(protobuf_direction as i32)
2507 });
2508 Some(PlacementVariant::Tiled(ProtobufTiledPlacement {
2509 direction,
2510 borderless,
2511 }))
2512 },
2513 NewPanePlacement::Floating(coords) => {
2514 let coordinates = coords.and_then(|c| c.try_into().ok());
2515 Some(PlacementVariant::Floating(ProtobufFloatingPlacement {
2516 coordinates,
2517 }))
2518 },
2519 NewPanePlacement::InPlace {
2520 pane_id_to_replace,
2521 close_replaced_pane,
2522 borderless,
2523 } => {
2524 let pane_id_to_replace = pane_id_to_replace.and_then(|id| id.try_into().ok());
2525 Some(PlacementVariant::InPlace(ProtobufInPlaceConfig {
2526 pane_id_to_replace,
2527 close_replaced_pane,
2528 borderless,
2529 }))
2530 },
2531 NewPanePlacement::Stacked {
2532 pane_id_to_stack_under,
2533 borderless,
2534 } => {
2535 let pane_id = pane_id_to_stack_under.and_then(|id| id.try_into().ok());
2536 Some(PlacementVariant::Stacked(ProtobufStackedPlacement {
2537 pane_id,
2538 borderless,
2539 }))
2540 },
2541 };
2542
2543 Ok(ProtobufNewPanePlacement { placement_variant })
2544 }
2545}
2546
2547impl TryFrom<ProtobufPercentOrFixed> for PercentOrFixed {
2550 type Error = &'static str;
2551 fn try_from(protobuf: ProtobufPercentOrFixed) -> Result<Self, Self::Error> {
2552 use super::generated_api::api::action::percent_or_fixed::SizeType;
2553 match protobuf.size_type {
2554 Some(SizeType::Percent(p)) => Ok(PercentOrFixed::Percent(p as usize)),
2555 Some(SizeType::Fixed(f)) => Ok(PercentOrFixed::Fixed(f as usize)),
2556 None => Err("PercentOrFixed must have a size_type"),
2557 }
2558 }
2559}
2560
2561impl TryFrom<PercentOrFixed> for ProtobufPercentOrFixed {
2562 type Error = &'static str;
2563 fn try_from(internal: PercentOrFixed) -> Result<Self, Self::Error> {
2564 use super::generated_api::api::action::percent_or_fixed::SizeType;
2565 let size_type = match internal {
2566 PercentOrFixed::Percent(p) => Some(SizeType::Percent(p as u32)),
2567 PercentOrFixed::Fixed(f) => Some(SizeType::Fixed(f as u32)),
2568 };
2569 Ok(ProtobufPercentOrFixed { size_type })
2570 }
2571}
2572
2573impl TryFrom<ProtobufSplitDirection> for SplitDirection {
2574 type Error = &'static str;
2575 fn try_from(protobuf: ProtobufSplitDirection) -> Result<Self, Self::Error> {
2576 match protobuf {
2577 ProtobufSplitDirection::Horizontal => Ok(SplitDirection::Horizontal),
2578 ProtobufSplitDirection::Vertical => Ok(SplitDirection::Vertical),
2579 ProtobufSplitDirection::Unspecified => Err("SplitDirection cannot be unspecified"),
2580 }
2581 }
2582}
2583
2584impl TryFrom<SplitDirection> for ProtobufSplitDirection {
2585 type Error = &'static str;
2586 fn try_from(internal: SplitDirection) -> Result<Self, Self::Error> {
2587 Ok(match internal {
2588 SplitDirection::Horizontal => ProtobufSplitDirection::Horizontal,
2589 SplitDirection::Vertical => ProtobufSplitDirection::Vertical,
2590 })
2591 }
2592}
2593
2594impl TryFrom<ProtobufLayoutConstraint> for LayoutConstraint {
2595 type Error = &'static str;
2596 fn try_from(protobuf: ProtobufLayoutConstraint) -> Result<Self, Self::Error> {
2597 match protobuf {
2598 ProtobufLayoutConstraint::MaxPanes => Ok(LayoutConstraint::MaxPanes(0)),
2599 ProtobufLayoutConstraint::MinPanes => Ok(LayoutConstraint::MinPanes(0)),
2600 ProtobufLayoutConstraint::ExactPanes => Ok(LayoutConstraint::ExactPanes(0)),
2601 ProtobufLayoutConstraint::NoConstraint => Ok(LayoutConstraint::NoConstraint),
2602 ProtobufLayoutConstraint::Unspecified => Err("LayoutConstraint cannot be unspecified"),
2603 }
2604 }
2605}
2606
2607impl TryFrom<LayoutConstraint> for ProtobufLayoutConstraint {
2608 type Error = &'static str;
2609 fn try_from(internal: LayoutConstraint) -> Result<Self, Self::Error> {
2610 Ok(match internal {
2611 LayoutConstraint::MaxPanes(_) => ProtobufLayoutConstraint::MaxPanes,
2612 LayoutConstraint::MinPanes(_) => ProtobufLayoutConstraint::MinPanes,
2613 LayoutConstraint::ExactPanes(_) => ProtobufLayoutConstraint::ExactPanes,
2614 LayoutConstraint::NoConstraint => ProtobufLayoutConstraint::NoConstraint,
2615 })
2616 }
2617}
2618
2619impl TryFrom<ProtobufLayoutConstraintWithValue> for LayoutConstraint {
2620 type Error = &'static str;
2621 fn try_from(protobuf: ProtobufLayoutConstraintWithValue) -> Result<Self, Self::Error> {
2622 let constraint_type = ProtobufLayoutConstraint::from_i32(protobuf.constraint_type)
2623 .ok_or("Invalid constraint type")?;
2624 match constraint_type {
2625 ProtobufLayoutConstraint::MaxPanes => Ok(LayoutConstraint::MaxPanes(
2626 protobuf.value.unwrap_or(0) as usize,
2627 )),
2628 ProtobufLayoutConstraint::MinPanes => Ok(LayoutConstraint::MinPanes(
2629 protobuf.value.unwrap_or(0) as usize,
2630 )),
2631 ProtobufLayoutConstraint::ExactPanes => Ok(LayoutConstraint::ExactPanes(
2632 protobuf.value.unwrap_or(0) as usize,
2633 )),
2634 ProtobufLayoutConstraint::NoConstraint => Ok(LayoutConstraint::NoConstraint),
2635 ProtobufLayoutConstraint::Unspecified => Err("LayoutConstraint cannot be unspecified"),
2636 }
2637 }
2638}
2639
2640impl TryFrom<LayoutConstraint> for ProtobufLayoutConstraintWithValue {
2641 type Error = &'static str;
2642 fn try_from(internal: LayoutConstraint) -> Result<Self, Self::Error> {
2643 let (constraint_type, value) = match internal {
2644 LayoutConstraint::MaxPanes(v) => {
2645 (ProtobufLayoutConstraint::MaxPanes as i32, Some(v as u32))
2646 },
2647 LayoutConstraint::MinPanes(v) => {
2648 (ProtobufLayoutConstraint::MinPanes as i32, Some(v as u32))
2649 },
2650 LayoutConstraint::ExactPanes(v) => {
2651 (ProtobufLayoutConstraint::ExactPanes as i32, Some(v as u32))
2652 },
2653 LayoutConstraint::NoConstraint => (ProtobufLayoutConstraint::NoConstraint as i32, None),
2654 };
2655 Ok(ProtobufLayoutConstraintWithValue {
2656 constraint_type,
2657 value,
2658 })
2659 }
2660}
2661
2662impl TryFrom<ProtobufPluginTag> for PluginTag {
2663 type Error = &'static str;
2664 fn try_from(protobuf: ProtobufPluginTag) -> Result<Self, Self::Error> {
2665 Ok(PluginTag::new(protobuf.tag))
2666 }
2667}
2668
2669impl TryFrom<PluginTag> for ProtobufPluginTag {
2670 type Error = &'static str;
2671 fn try_from(internal: PluginTag) -> Result<Self, Self::Error> {
2672 Ok(ProtobufPluginTag {
2673 tag: internal.into(),
2674 })
2675 }
2676}
2677
2678impl TryFrom<ProtobufPluginUserConfiguration> for PluginUserConfiguration {
2679 type Error = &'static str;
2680 fn try_from(protobuf: ProtobufPluginUserConfiguration) -> Result<Self, Self::Error> {
2681 let btree_map: BTreeMap<String, String> = protobuf.configuration.into_iter().collect();
2682 Ok(PluginUserConfiguration::new(btree_map))
2683 }
2684}
2685
2686impl TryFrom<PluginUserConfiguration> for ProtobufPluginUserConfiguration {
2687 type Error = &'static str;
2688 fn try_from(internal: PluginUserConfiguration) -> Result<Self, Self::Error> {
2689 let configuration = internal.inner().clone().into_iter().collect();
2690 Ok(ProtobufPluginUserConfiguration { configuration })
2691 }
2692}
2693
2694impl TryFrom<ProtobufRunPluginLocationData> for RunPluginLocation {
2695 type Error = &'static str;
2696 fn try_from(protobuf: ProtobufRunPluginLocationData) -> Result<Self, Self::Error> {
2697 use super::generated_api::api::action::run_plugin_location_data::LocationData;
2698 match protobuf.location_data {
2699 Some(LocationData::FilePath(path)) => Ok(RunPluginLocation::File(PathBuf::from(path))),
2700 Some(LocationData::ZellijTag(tag)) => Ok(RunPluginLocation::Zellij(tag.try_into()?)),
2701 Some(LocationData::RemoteUrl(url)) => Ok(RunPluginLocation::Remote(url)),
2702 None => Err("RunPluginLocationData must have location_data"),
2703 }
2704 }
2705}
2706
2707impl TryFrom<RunPluginLocation> for ProtobufRunPluginLocationData {
2708 type Error = &'static str;
2709 fn try_from(internal: RunPluginLocation) -> Result<Self, Self::Error> {
2710 use super::generated_api::api::action::{
2711 run_plugin_location_data::LocationData,
2712 RunPluginLocation as ProtobufRunPluginLocationType,
2713 };
2714 let (location_type, location_data) = match internal {
2715 RunPluginLocation::File(path) => (
2716 ProtobufRunPluginLocationType::File as i32,
2717 Some(LocationData::FilePath(path.display().to_string())),
2718 ),
2719 RunPluginLocation::Zellij(tag) => (
2720 ProtobufRunPluginLocationType::Zellij as i32,
2721 Some(LocationData::ZellijTag(tag.try_into()?)),
2722 ),
2723 RunPluginLocation::Remote(url) => (
2724 ProtobufRunPluginLocationType::Remote as i32,
2725 Some(LocationData::RemoteUrl(url)),
2726 ),
2727 };
2728 Ok(ProtobufRunPluginLocationData {
2729 location_type,
2730 location_data,
2731 })
2732 }
2733}
2734
2735impl TryFrom<ProtobufRunPlugin> for RunPlugin {
2736 type Error = &'static str;
2737 fn try_from(protobuf: ProtobufRunPlugin) -> Result<Self, Self::Error> {
2738 let location = protobuf
2739 .location
2740 .ok_or("RunPlugin must have location")?
2741 .try_into()?;
2742 let configuration = protobuf
2743 .configuration
2744 .ok_or("RunPlugin must have configuration")?
2745 .try_into()?;
2746 let initial_cwd = protobuf.initial_cwd.map(PathBuf::from);
2747 Ok(RunPlugin {
2748 _allow_exec_host_cmd: protobuf.allow_exec_host_cmd,
2749 location,
2750 configuration,
2751 initial_cwd,
2752 })
2753 }
2754}
2755
2756impl TryFrom<RunPlugin> for ProtobufRunPlugin {
2757 type Error = &'static str;
2758 fn try_from(internal: RunPlugin) -> Result<Self, Self::Error> {
2759 Ok(ProtobufRunPlugin {
2760 allow_exec_host_cmd: internal._allow_exec_host_cmd,
2761 location: Some(internal.location.try_into()?),
2762 configuration: Some(internal.configuration.try_into()?),
2763 initial_cwd: internal.initial_cwd.map(|p| p.display().to_string()),
2764 })
2765 }
2766}
2767
2768impl TryFrom<ProtobufPluginAlias> for PluginAlias {
2769 type Error = &'static str;
2770 fn try_from(protobuf: ProtobufPluginAlias) -> Result<Self, Self::Error> {
2771 let configuration = protobuf.configuration.map(|c| c.try_into()).transpose()?;
2772 let initial_cwd = protobuf.initial_cwd.map(PathBuf::from);
2773 let run_plugin = protobuf.run_plugin.map(|r| r.try_into()).transpose()?;
2774 Ok(PluginAlias {
2775 name: protobuf.name,
2776 configuration,
2777 initial_cwd,
2778 run_plugin,
2779 })
2780 }
2781}
2782
2783impl TryFrom<PluginAlias> for ProtobufPluginAlias {
2784 type Error = &'static str;
2785 fn try_from(internal: PluginAlias) -> Result<Self, Self::Error> {
2786 Ok(ProtobufPluginAlias {
2787 name: internal.name,
2788 configuration: internal.configuration.map(|c| c.try_into()).transpose()?,
2789 initial_cwd: internal.initial_cwd.map(|p| p.display().to_string()),
2790 run_plugin: internal.run_plugin.map(|r| r.try_into()).transpose()?,
2791 })
2792 }
2793}
2794
2795impl TryFrom<ProtobufRunPluginOrAlias> for RunPluginOrAlias {
2796 type Error = &'static str;
2797 fn try_from(protobuf: ProtobufRunPluginOrAlias) -> Result<Self, Self::Error> {
2798 use super::generated_api::api::action::run_plugin_or_alias::PluginType;
2799 match protobuf.plugin_type {
2800 Some(PluginType::Plugin(plugin)) => Ok(RunPluginOrAlias::RunPlugin(plugin.try_into()?)),
2801 Some(PluginType::Alias(alias)) => Ok(RunPluginOrAlias::Alias(alias.try_into()?)),
2802 None => Err("RunPluginOrAlias must have plugin_type"),
2803 }
2804 }
2805}
2806
2807impl TryFrom<RunPluginOrAlias> for ProtobufRunPluginOrAlias {
2808 type Error = &'static str;
2809 fn try_from(internal: RunPluginOrAlias) -> Result<Self, Self::Error> {
2810 use super::generated_api::api::action::run_plugin_or_alias::PluginType;
2811 let plugin_type = match internal {
2812 RunPluginOrAlias::RunPlugin(plugin) => Some(PluginType::Plugin(plugin.try_into()?)),
2813 RunPluginOrAlias::Alias(alias) => Some(PluginType::Alias(alias.try_into()?)),
2814 };
2815 Ok(ProtobufRunPluginOrAlias { plugin_type })
2816 }
2817}
2818
2819impl TryFrom<ProtobufRunEditFileAction> for Run {
2820 type Error = &'static str;
2821 fn try_from(protobuf: ProtobufRunEditFileAction) -> Result<Self, Self::Error> {
2822 let file_path = PathBuf::from(protobuf.file_path);
2823 let line_number = protobuf.line_number.map(|n| n as usize);
2824 let cwd = protobuf.cwd.map(PathBuf::from);
2825 Ok(Run::EditFile(file_path, line_number, cwd))
2826 }
2827}
2828
2829impl TryFrom<ProtobufPaneRun> for Run {
2830 type Error = &'static str;
2831 fn try_from(protobuf: ProtobufPaneRun) -> Result<Self, Self::Error> {
2832 use super::generated_api::api::action::pane_run::RunType;
2833 use crate::input::command::RunCommand;
2834 match protobuf.run_type {
2835 Some(RunType::Command(cmd)) => {
2836 let run_command_action: RunCommandAction = cmd.try_into()?;
2837 let run_command: RunCommand = run_command_action.into();
2838 Ok(Run::Command(run_command))
2839 },
2840 Some(RunType::Plugin(plugin)) => Ok(Run::Plugin(plugin.try_into()?)),
2841 Some(RunType::EditFile(edit)) => edit.try_into(),
2842 Some(RunType::Cwd(cwd)) => Ok(Run::Cwd(PathBuf::from(cwd))),
2843 None => Err("PaneRun must have run_type"),
2844 }
2845 }
2846}
2847
2848impl TryFrom<Run> for ProtobufPaneRun {
2849 type Error = &'static str;
2850 fn try_from(internal: Run) -> Result<Self, Self::Error> {
2851 use super::generated_api::api::action::pane_run::RunType;
2852 let run_type = match internal {
2853 Run::Command(cmd) => {
2854 let run_command_action: RunCommandAction = cmd.into();
2855 Some(RunType::Command(run_command_action.try_into()?))
2856 },
2857 Run::Plugin(plugin) => Some(RunType::Plugin(plugin.try_into()?)),
2858 Run::EditFile(file_path, line_number, cwd) => {
2859 Some(RunType::EditFile(ProtobufRunEditFileAction {
2860 file_path: file_path.display().to_string(),
2861 line_number: line_number.map(|n| n as u32),
2862 cwd: cwd.map(|p| p.display().to_string()),
2863 }))
2864 },
2865 Run::Cwd(cwd) => Some(RunType::Cwd(cwd.display().to_string())),
2866 };
2867 Ok(ProtobufPaneRun { run_type })
2868 }
2869}
2870
2871impl TryFrom<ProtobufCommandOrPlugin> for CommandOrPlugin {
2872 type Error = &'static str;
2873 fn try_from(protobuf: ProtobufCommandOrPlugin) -> Result<Self, Self::Error> {
2874 use super::generated_api::api::action::command_or_plugin::CommandOrPluginType;
2875 match protobuf.command_or_plugin_type {
2876 Some(CommandOrPluginType::Command(cmd)) => {
2877 Ok(CommandOrPlugin::Command(cmd.try_into()?))
2878 },
2879 Some(CommandOrPluginType::Plugin(plugin)) => {
2880 Ok(CommandOrPlugin::Plugin(plugin.try_into()?))
2881 },
2882 Some(CommandOrPluginType::File(f)) => {
2883 Ok(CommandOrPlugin::File(crate::data::FileToOpen {
2884 path: std::path::PathBuf::from(&f.path),
2885 line_number: f.line_number.map(|n| n as usize),
2886 cwd: f.cwd.map(std::path::PathBuf::from),
2887 }))
2888 },
2889 None => Err("CommandOrPlugin must have command_or_plugin_type"),
2890 }
2891 }
2892}
2893
2894impl TryFrom<CommandOrPlugin> for ProtobufCommandOrPlugin {
2895 type Error = &'static str;
2896 fn try_from(internal: CommandOrPlugin) -> Result<Self, Self::Error> {
2897 use super::generated_api::api::action::command_or_plugin::CommandOrPluginType;
2898 use super::generated_api::api::action::CommandOrPluginFile;
2899 let command_or_plugin_type = match internal {
2900 CommandOrPlugin::Command(cmd) => Some(CommandOrPluginType::Command(cmd.try_into()?)),
2901 CommandOrPlugin::Plugin(plugin) => {
2902 Some(CommandOrPluginType::Plugin(plugin.try_into()?))
2903 },
2904 CommandOrPlugin::File(f) => Some(CommandOrPluginType::File(CommandOrPluginFile {
2905 path: f.path.display().to_string(),
2906 line_number: f.line_number.map(|n| n as i32),
2907 cwd: f.cwd.map(|c| c.display().to_string()),
2908 })),
2909 };
2910 Ok(ProtobufCommandOrPlugin {
2911 command_or_plugin_type,
2912 })
2913 }
2914}
2915
2916impl TryFrom<ProtobufTabLayoutInfo> for TabLayoutInfo {
2917 type Error = &'static str;
2918
2919 fn try_from(protobuf_tab: ProtobufTabLayoutInfo) -> Result<Self, Self::Error> {
2920 Ok(TabLayoutInfo {
2921 tab_index: protobuf_tab.tab_index as usize,
2922 tab_name: protobuf_tab.tab_name.filter(|s| !s.is_empty()),
2923 tiled_layout: protobuf_tab
2924 .tiled_layout
2925 .ok_or("missing tiled_layout")?
2926 .try_into()?,
2927 floating_layouts: protobuf_tab
2928 .floating_layouts
2929 .into_iter()
2930 .map(|l| l.try_into())
2931 .collect::<Result<Vec<_>, _>>()?,
2932 swap_tiled_layouts: if protobuf_tab.swap_tiled_layouts.is_empty() {
2933 None
2934 } else {
2935 Some(
2936 protobuf_tab
2937 .swap_tiled_layouts
2938 .into_iter()
2939 .map(|l| l.try_into())
2940 .collect::<Result<Vec<_>, _>>()?,
2941 )
2942 },
2943 swap_floating_layouts: if protobuf_tab.swap_floating_layouts.is_empty() {
2944 None
2945 } else {
2946 Some(
2947 protobuf_tab
2948 .swap_floating_layouts
2949 .into_iter()
2950 .map(|l| l.try_into())
2951 .collect::<Result<Vec<_>, _>>()?,
2952 )
2953 },
2954 })
2955 }
2956}
2957
2958impl TryFrom<TabLayoutInfo> for ProtobufTabLayoutInfo {
2959 type Error = &'static str;
2960
2961 fn try_from(tab_info: TabLayoutInfo) -> Result<Self, Self::Error> {
2962 Ok(ProtobufTabLayoutInfo {
2963 tab_index: tab_info.tab_index as u32,
2964 tab_name: tab_info.tab_name,
2965 tiled_layout: Some(tab_info.tiled_layout.try_into()?),
2966 floating_layouts: tab_info
2967 .floating_layouts
2968 .into_iter()
2969 .map(|l| l.try_into())
2970 .collect::<Result<Vec<_>, _>>()?,
2971 swap_tiled_layouts: tab_info
2972 .swap_tiled_layouts
2973 .unwrap_or_default()
2974 .into_iter()
2975 .map(|l| l.try_into())
2976 .collect::<Result<Vec<_>, _>>()?,
2977 swap_floating_layouts: tab_info
2978 .swap_floating_layouts
2979 .unwrap_or_default()
2980 .into_iter()
2981 .map(|l| l.try_into())
2982 .collect::<Result<Vec<_>, _>>()?,
2983 })
2984 }
2985}
2986
2987impl TryFrom<ProtobufTiledPaneLayout> for TiledPaneLayout {
2988 type Error = &'static str;
2989 fn try_from(protobuf: ProtobufTiledPaneLayout) -> Result<Self, Self::Error> {
2990 let children_split_direction =
2991 ProtobufSplitDirection::from_i32(protobuf.children_split_direction)
2992 .ok_or("Invalid split direction")?
2993 .try_into()?;
2994 let children = protobuf
2995 .children
2996 .into_iter()
2997 .map(|c| c.try_into())
2998 .collect::<Result<Vec<_>, _>>()?;
2999 let split_size = protobuf.split_size.map(|s| s.try_into()).transpose()?;
3000 let run = protobuf.run.map(|r| r.try_into()).transpose()?;
3001 let focus = protobuf.focus.and_then(|f| {
3002 if f == "true" {
3003 Some(true)
3004 } else if f == "false" {
3005 Some(false)
3006 } else {
3007 None
3008 }
3009 });
3010 let run_instructions_to_ignore = vec![]; Ok(TiledPaneLayout {
3012 children_split_direction,
3013 name: protobuf.name,
3014 children,
3015 split_size,
3016 run,
3017 borderless: Some(protobuf.borderless),
3018 focus,
3019 external_children_index: protobuf.external_children_index.map(|i| i as usize),
3020 children_are_stacked: protobuf.children_are_stacked,
3021 is_expanded_in_stack: protobuf.is_expanded_in_stack,
3022 exclude_from_sync: protobuf.exclude_from_sync,
3023 run_instructions_to_ignore,
3024 hide_floating_panes: protobuf.hide_floating_panes,
3025 pane_initial_contents: protobuf.pane_initial_contents,
3026 default_fg: None,
3027 default_bg: None,
3028 })
3029 }
3030}
3031
3032impl TryFrom<TiledPaneLayout> for ProtobufTiledPaneLayout {
3033 type Error = &'static str;
3034 fn try_from(internal: TiledPaneLayout) -> Result<Self, Self::Error> {
3035 let children_split_direction: ProtobufSplitDirection =
3036 internal.children_split_direction.try_into()?;
3037 let children = internal
3038 .children
3039 .into_iter()
3040 .map(|c| c.try_into())
3041 .collect::<Result<Vec<_>, _>>()?;
3042 let split_size = internal.split_size.map(|s| s.try_into()).transpose()?;
3043 let run = internal.run.map(|r| r.try_into()).transpose()?;
3044 let focus = internal.focus.map(|f| f.to_string());
3045 Ok(ProtobufTiledPaneLayout {
3046 children_split_direction: children_split_direction as i32,
3047 name: internal.name,
3048 children,
3049 split_size,
3050 run,
3051 borderless: internal.borderless.unwrap_or(false),
3052 focus,
3053 external_children_index: internal.external_children_index.map(|i| i as u32),
3054 children_are_stacked: internal.children_are_stacked,
3055 is_expanded_in_stack: internal.is_expanded_in_stack,
3056 exclude_from_sync: internal.exclude_from_sync,
3057 hide_floating_panes: internal.hide_floating_panes,
3058 pane_initial_contents: internal.pane_initial_contents,
3059 })
3060 }
3061}
3062
3063impl TryFrom<ProtobufFloatingPaneLayout> for FloatingPaneLayout {
3064 type Error = &'static str;
3065 fn try_from(protobuf: ProtobufFloatingPaneLayout) -> Result<Self, Self::Error> {
3066 let height = protobuf.height.map(|h| h.try_into()).transpose()?;
3067 let width = protobuf.width.map(|w| w.try_into()).transpose()?;
3068 let x = protobuf.x.map(|x| x.try_into()).transpose()?;
3069 let y = protobuf.y.map(|y| y.try_into()).transpose()?;
3070 let run = protobuf.run.map(|r| r.try_into()).transpose()?;
3071 Ok(FloatingPaneLayout {
3072 name: protobuf.name,
3073 height,
3074 width,
3075 x,
3076 y,
3077 pinned: protobuf.pinned,
3078 run,
3079 focus: protobuf.focus,
3080 already_running: protobuf.already_running,
3081 pane_initial_contents: protobuf.pane_initial_contents,
3082 logical_position: protobuf.logical_position.map(|p| p as usize),
3083 borderless: protobuf.borderless,
3084 default_fg: None,
3085 default_bg: None,
3086 })
3087 }
3088}
3089
3090impl TryFrom<FloatingPaneLayout> for ProtobufFloatingPaneLayout {
3091 type Error = &'static str;
3092 fn try_from(internal: FloatingPaneLayout) -> Result<Self, Self::Error> {
3093 let height = internal.height.map(|h| h.try_into()).transpose()?;
3094 let width = internal.width.map(|w| w.try_into()).transpose()?;
3095 let x = internal.x.map(|x| x.try_into()).transpose()?;
3096 let y = internal.y.map(|y| y.try_into()).transpose()?;
3097 let run = internal.run.map(|r| r.try_into()).transpose()?;
3098 Ok(ProtobufFloatingPaneLayout {
3099 name: internal.name,
3100 height,
3101 width,
3102 x,
3103 y,
3104 pinned: internal.pinned,
3105 run,
3106 focus: internal.focus,
3107 already_running: internal.already_running,
3108 pane_initial_contents: internal.pane_initial_contents,
3109 logical_position: internal.logical_position.map(|p| p as u32),
3110 borderless: internal.borderless,
3111 })
3112 }
3113}
3114
3115impl TryFrom<ProtobufLayoutConstraintTiledPair> for (LayoutConstraint, TiledPaneLayout) {
3116 type Error = &'static str;
3117 fn try_from(protobuf: ProtobufLayoutConstraintTiledPair) -> Result<Self, Self::Error> {
3118 let constraint = protobuf
3119 .constraint
3120 .ok_or("LayoutConstraintTiledPair must have constraint")?
3121 .try_into()?;
3122 let layout = protobuf
3123 .layout
3124 .ok_or("LayoutConstraintTiledPair must have layout")?
3125 .try_into()?;
3126 Ok((constraint, layout))
3127 }
3128}
3129
3130impl TryFrom<(LayoutConstraint, TiledPaneLayout)> for ProtobufLayoutConstraintTiledPair {
3131 type Error = &'static str;
3132 fn try_from(internal: (LayoutConstraint, TiledPaneLayout)) -> Result<Self, Self::Error> {
3133 Ok(ProtobufLayoutConstraintTiledPair {
3134 constraint: Some(internal.0.try_into()?),
3135 layout: Some(internal.1.try_into()?),
3136 })
3137 }
3138}
3139
3140impl TryFrom<ProtobufLayoutConstraintFloatingPair> for (LayoutConstraint, Vec<FloatingPaneLayout>) {
3141 type Error = &'static str;
3142 fn try_from(protobuf: ProtobufLayoutConstraintFloatingPair) -> Result<Self, Self::Error> {
3143 let constraint = protobuf
3144 .constraint
3145 .ok_or("LayoutConstraintFloatingPair must have constraint")?
3146 .try_into()?;
3147 let layouts = protobuf
3148 .layouts
3149 .into_iter()
3150 .map(|l| l.try_into())
3151 .collect::<Result<Vec<_>, _>>()?;
3152 Ok((constraint, layouts))
3153 }
3154}
3155
3156impl TryFrom<(LayoutConstraint, Vec<FloatingPaneLayout>)> for ProtobufLayoutConstraintFloatingPair {
3157 type Error = &'static str;
3158 fn try_from(
3159 internal: (LayoutConstraint, Vec<FloatingPaneLayout>),
3160 ) -> Result<Self, Self::Error> {
3161 Ok(ProtobufLayoutConstraintFloatingPair {
3162 constraint: Some(internal.0.try_into()?),
3163 layouts: internal
3164 .1
3165 .into_iter()
3166 .map(|l| l.try_into())
3167 .collect::<Result<Vec<_>, _>>()?,
3168 })
3169 }
3170}
3171
3172impl TryFrom<ProtobufSwapTiledLayout> for SwapTiledLayout {
3173 type Error = &'static str;
3174 fn try_from(protobuf: ProtobufSwapTiledLayout) -> Result<Self, Self::Error> {
3175 let constraint_map: BTreeMap<LayoutConstraint, TiledPaneLayout> = protobuf
3176 .constraint_map
3177 .into_iter()
3178 .map(|pair| pair.try_into())
3179 .collect::<Result<BTreeMap<_, _>, _>>()?;
3180 Ok((constraint_map, protobuf.name))
3181 }
3182}
3183
3184impl TryFrom<SwapTiledLayout> for ProtobufSwapTiledLayout {
3185 type Error = &'static str;
3186 fn try_from(internal: SwapTiledLayout) -> Result<Self, Self::Error> {
3187 let constraint_map = internal
3188 .0
3189 .into_iter()
3190 .map(|(constraint, layout)| (constraint, layout).try_into())
3191 .collect::<Result<Vec<_>, _>>()?;
3192 Ok(ProtobufSwapTiledLayout {
3193 constraint_map,
3194 name: internal.1,
3195 })
3196 }
3197}
3198
3199impl TryFrom<ProtobufSwapFloatingLayout> for SwapFloatingLayout {
3200 type Error = &'static str;
3201 fn try_from(protobuf: ProtobufSwapFloatingLayout) -> Result<Self, Self::Error> {
3202 let constraint_map: BTreeMap<LayoutConstraint, Vec<FloatingPaneLayout>> = protobuf
3203 .constraint_map
3204 .into_iter()
3205 .map(|pair| pair.try_into())
3206 .collect::<Result<BTreeMap<_, _>, _>>()?;
3207 Ok((constraint_map, protobuf.name))
3208 }
3209}
3210
3211impl TryFrom<SwapFloatingLayout> for ProtobufSwapFloatingLayout {
3212 type Error = &'static str;
3213 fn try_from(internal: SwapFloatingLayout) -> Result<Self, Self::Error> {
3214 let constraint_map = internal
3215 .0
3216 .into_iter()
3217 .map(|(constraint, layouts)| (constraint, layouts).try_into())
3218 .collect::<Result<Vec<_>, _>>()?;
3219 Ok(ProtobufSwapFloatingLayout {
3220 constraint_map,
3221 name: internal.1,
3222 })
3223 }
3224}