Skip to main content

taskers_control/
protocol.rs

1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4use taskers_domain::{
5    AppModel, Direction, PaneId, PaneKind, PaneMetadataPatch, PersistedSession, SignalEvent,
6    SplitAxis, SurfaceId, WindowFrame, WindowId, WorkspaceId, WorkspaceViewport, WorkspaceWindowId,
7};
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10#[serde(tag = "command", rename_all = "snake_case")]
11pub enum ControlCommand {
12    CreateWorkspace {
13        label: String,
14    },
15    RenameWorkspace {
16        workspace_id: WorkspaceId,
17        label: String,
18    },
19    SwitchWorkspace {
20        window_id: Option<WindowId>,
21        workspace_id: WorkspaceId,
22    },
23    SplitPane {
24        workspace_id: WorkspaceId,
25        pane_id: Option<PaneId>,
26        axis: SplitAxis,
27    },
28    CreateWorkspaceWindow {
29        workspace_id: WorkspaceId,
30        direction: Direction,
31    },
32    FocusWorkspaceWindow {
33        workspace_id: WorkspaceId,
34        workspace_window_id: WorkspaceWindowId,
35    },
36    FocusPane {
37        workspace_id: WorkspaceId,
38        pane_id: PaneId,
39    },
40    FocusPaneDirection {
41        workspace_id: WorkspaceId,
42        direction: Direction,
43    },
44    ResizeActiveWindow {
45        workspace_id: WorkspaceId,
46        direction: Direction,
47        amount: i32,
48    },
49    ResizeActivePaneSplit {
50        workspace_id: WorkspaceId,
51        direction: Direction,
52        amount: i32,
53    },
54    SetWorkspaceWindowFrame {
55        workspace_id: WorkspaceId,
56        workspace_window_id: WorkspaceWindowId,
57        frame: WindowFrame,
58    },
59    SetWindowSplitRatio {
60        workspace_id: WorkspaceId,
61        workspace_window_id: WorkspaceWindowId,
62        path: Vec<bool>,
63        ratio: u16,
64    },
65    UpdatePaneMetadata {
66        pane_id: PaneId,
67        patch: PaneMetadataPatch,
68    },
69    UpdateSurfaceMetadata {
70        surface_id: SurfaceId,
71        patch: PaneMetadataPatch,
72    },
73    CreateSurface {
74        workspace_id: WorkspaceId,
75        pane_id: PaneId,
76        kind: PaneKind,
77    },
78    FocusSurface {
79        workspace_id: WorkspaceId,
80        pane_id: PaneId,
81        surface_id: SurfaceId,
82    },
83    MarkSurfaceCompleted {
84        workspace_id: WorkspaceId,
85        pane_id: PaneId,
86        surface_id: SurfaceId,
87    },
88    CloseSurface {
89        workspace_id: WorkspaceId,
90        pane_id: PaneId,
91        surface_id: SurfaceId,
92    },
93    SetWorkspaceViewport {
94        workspace_id: WorkspaceId,
95        viewport: WorkspaceViewport,
96    },
97    ClosePane {
98        workspace_id: WorkspaceId,
99        pane_id: PaneId,
100    },
101    CloseWorkspace {
102        workspace_id: WorkspaceId,
103    },
104    EmitSignal {
105        workspace_id: WorkspaceId,
106        pane_id: PaneId,
107        surface_id: Option<SurfaceId>,
108        event: SignalEvent,
109    },
110    QueryStatus {
111        query: ControlQuery,
112    },
113}
114
115#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
116#[serde(tag = "scope", rename_all = "snake_case")]
117pub enum ControlQuery {
118    ActiveWindow,
119    Window { window_id: WindowId },
120    Workspace { workspace_id: WorkspaceId },
121    All,
122}
123
124#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
125#[serde(tag = "status", rename_all = "snake_case")]
126pub enum ControlResponse {
127    Ack {
128        message: String,
129    },
130    WorkspaceCreated {
131        workspace_id: WorkspaceId,
132    },
133    PaneSplit {
134        pane_id: PaneId,
135    },
136    SurfaceCreated {
137        surface_id: SurfaceId,
138    },
139    WorkspaceWindowCreated {
140        pane_id: PaneId,
141    },
142    Status {
143        session: PersistedSession,
144    },
145    WorkspaceState {
146        workspace_id: WorkspaceId,
147        session: PersistedSession,
148    },
149}
150
151#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
152pub struct RequestFrame {
153    pub request_id: Uuid,
154    pub command: ControlCommand,
155}
156
157#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
158pub struct ResponseFrame {
159    pub request_id: Uuid,
160    pub response: Result<ControlResponse, String>,
161}
162
163impl RequestFrame {
164    pub fn new(command: ControlCommand) -> Self {
165        Self {
166            request_id: Uuid::now_v7(),
167            command,
168        }
169    }
170}
171
172impl From<AppModel> for ControlResponse {
173    fn from(model: AppModel) -> Self {
174        Self::Status {
175            session: model.snapshot(),
176        }
177    }
178}