Skip to main content

rmux_sdk/
types.rs

1//! SDK type vocabulary.
2//!
3//! Identity newtypes are defined exactly once in `rmux-proto`. This module
4//! re-exports the four authoritative identity types (`SessionName`,
5//! `SessionId`, `WindowId`, `PaneId`) so SDK users never have to depend on
6//! `rmux-core`, `rmux-server`, `rmux-client`, or `rmux-pty` to obtain
7//! them. The SDK does not redeclare these newtypes; `rmux-proto` is the
8//! single public home for the identity vocabulary.
9
10use std::path::PathBuf;
11
12use serde::{Deserialize, Serialize};
13
14pub use rmux_proto::{PaneId, SessionId, SessionName, WindowId};
15
16/// Selects the daemon endpoint resolution strategy used by the SDK.
17///
18/// `Default` defers to SDK runtime discovery, falling through to platform
19/// defaults resolved through the existing RMUX IPC/OS layer when no SDK
20/// environment override is accepted. The explicit variants carry
21/// caller-supplied paths/names and bypass the auto-discovery allowlist while
22/// still preserving the daemon's own permission and symlink checks.
23///
24/// Marked `#[non_exhaustive]` because additional transports (such as TCP
25/// or test-harness in-memory pipes) are anticipated in later steps and
26/// must be addable without breaking downstream pattern matches.
27#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
28#[non_exhaustive]
29pub enum RmuxEndpoint {
30    /// Resolve through SDK discovery, falling through to the platform default.
31    #[default]
32    Default,
33    /// Use an explicit Unix domain socket path.
34    UnixSocket(PathBuf),
35    /// Use an explicit Windows named pipe identifier.
36    WindowsPipe(String),
37}
38
39impl RmuxEndpoint {
40    /// Returns `true` when this endpoint defers to platform default
41    /// resolution.
42    #[must_use]
43    pub fn is_default(&self) -> bool {
44        matches!(self, Self::Default)
45    }
46}
47
48/// Terminal geometry carried by SDK value objects.
49///
50/// This is an inert DTO. Converting it to the protocol type does not inspect
51/// the caller's terminal or normalize zero dimensions.
52#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
53pub struct TerminalSizeSpec {
54    /// Requested terminal columns.
55    pub cols: u16,
56    /// Requested terminal rows.
57    pub rows: u16,
58}
59
60impl TerminalSizeSpec {
61    /// Creates a terminal-size DTO from explicit column and row counts.
62    #[must_use]
63    pub const fn new(cols: u16, rows: u16) -> Self {
64        Self { cols, rows }
65    }
66}
67
68impl From<TerminalSizeSpec> for rmux_proto::TerminalSize {
69    fn from(value: TerminalSizeSpec) -> Self {
70        Self {
71            cols: value.cols,
72            rows: value.rows,
73        }
74    }
75}
76
77impl From<rmux_proto::TerminalSize> for TerminalSizeSpec {
78    fn from(value: rmux_proto::TerminalSize) -> Self {
79        Self {
80            cols: value.cols,
81            rows: value.rows,
82        }
83    }
84}
85
86/// Exact window selector used by SDK DTOs.
87///
88/// This type stores already-structured target components. It deliberately
89/// performs no tmux target parsing or server-side lookup.
90#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
91pub struct WindowRef {
92    /// Exact session name component.
93    pub session_name: SessionName,
94    /// Exact window index component.
95    pub window_index: u32,
96}
97
98impl WindowRef {
99    /// Creates a window selector from explicit target components.
100    #[must_use]
101    pub fn new(session_name: SessionName, window_index: u32) -> Self {
102        Self {
103            session_name,
104            window_index,
105        }
106    }
107
108    /// Creates a selector for window index `0` in the given session.
109    #[must_use]
110    pub fn first(session_name: SessionName) -> Self {
111        Self::new(session_name, 0)
112    }
113
114    /// Converts this selector to the matching protocol target DTO.
115    #[must_use]
116    pub fn to_proto(&self) -> rmux_proto::WindowTarget {
117        rmux_proto::WindowTarget::with_window(self.session_name.clone(), self.window_index)
118    }
119}
120
121impl From<WindowRef> for rmux_proto::WindowTarget {
122    fn from(value: WindowRef) -> Self {
123        Self::with_window(value.session_name, value.window_index)
124    }
125}
126
127impl From<rmux_proto::WindowTarget> for WindowRef {
128    fn from(value: rmux_proto::WindowTarget) -> Self {
129        Self {
130            session_name: value.session_name().clone(),
131            window_index: value.window_index(),
132        }
133    }
134}
135
136impl From<&WindowRef> for rmux_proto::WindowTarget {
137    fn from(value: &WindowRef) -> Self {
138        value.to_proto()
139    }
140}
141
142/// Exact pane selector used by SDK DTOs.
143///
144/// This type stores already-structured target components. It deliberately
145/// performs no tmux target parsing or server-side lookup.
146#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
147pub struct PaneRef {
148    /// Exact session name component.
149    pub session_name: SessionName,
150    /// Exact window index component.
151    pub window_index: u32,
152    /// Exact pane index component.
153    pub pane_index: u32,
154}
155
156impl PaneRef {
157    /// Creates a pane selector from explicit target components.
158    #[must_use]
159    pub fn new(session_name: SessionName, window_index: u32, pane_index: u32) -> Self {
160        Self {
161            session_name,
162            window_index,
163            pane_index,
164        }
165    }
166
167    /// Creates a selector in window index `0`.
168    #[must_use]
169    pub fn in_first_window(session_name: SessionName, pane_index: u32) -> Self {
170        Self::new(session_name, 0, pane_index)
171    }
172
173    /// Converts this selector to the matching protocol target DTO.
174    #[must_use]
175    pub fn to_proto(&self) -> rmux_proto::PaneTarget {
176        rmux_proto::PaneTarget::with_window(
177            self.session_name.clone(),
178            self.window_index,
179            self.pane_index,
180        )
181    }
182}
183
184impl From<PaneRef> for rmux_proto::PaneTarget {
185    fn from(value: PaneRef) -> Self {
186        Self::with_window(value.session_name, value.window_index, value.pane_index)
187    }
188}
189
190impl From<rmux_proto::PaneTarget> for PaneRef {
191    fn from(value: rmux_proto::PaneTarget) -> Self {
192        Self {
193            session_name: value.session_name().clone(),
194            window_index: value.window_index(),
195            pane_index: value.pane_index(),
196        }
197    }
198}
199
200impl From<&PaneRef> for rmux_proto::PaneTarget {
201    fn from(value: &PaneRef) -> Self {
202        value.to_proto()
203    }
204}
205
206/// Exact target selector used by SDK DTOs that accept multiple target forms.
207///
208/// The enum stores structured components only; it does not parse tmux target
209/// strings or resolve ambiguous targets.
210#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
211pub enum TargetRef {
212    /// Exact session target.
213    Session(SessionName),
214    /// Exact window target.
215    Window(WindowRef),
216    /// Exact pane target.
217    Pane(PaneRef),
218}
219
220impl From<TargetRef> for rmux_proto::Target {
221    fn from(value: TargetRef) -> Self {
222        match value {
223            TargetRef::Session(session_name) => Self::Session(session_name),
224            TargetRef::Window(target) => Self::Window(target.into()),
225            TargetRef::Pane(target) => Self::Pane(target.into()),
226        }
227    }
228}
229
230impl From<rmux_proto::Target> for TargetRef {
231    fn from(value: rmux_proto::Target) -> Self {
232        match value {
233            rmux_proto::Target::Session(session_name) => Self::Session(session_name),
234            rmux_proto::Target::Window(target) => Self::Window(target.into()),
235            rmux_proto::Target::Pane(target) => Self::Pane(target.into()),
236        }
237    }
238}
239
240impl From<&TargetRef> for rmux_proto::Target {
241    fn from(value: &TargetRef) -> Self {
242        match value {
243            TargetRef::Session(session_name) => Self::Session(session_name.clone()),
244            TargetRef::Window(target) => Self::Window(target.into()),
245            TargetRef::Pane(target) => Self::Pane(target.into()),
246        }
247    }
248}