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