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