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