Skip to main content

rmux_client/commands/
session.rs

1use rmux_proto::request::{
2    AttachSessionExt2Request, AttachSessionExtRequest, DetachClientExtRequest, ListClientsRequest,
3    NewSessionExtRequest, RefreshClientRequest, Request, SuspendClientRequest,
4    SwitchClientExt2Request, SwitchClientExt3Request,
5};
6use rmux_proto::{
7    AttachSessionRequest, DetachClientRequest, HasSessionRequest, KillSessionRequest,
8    ListPanesRequest, ListSessionsRequest, NewSessionRequest, RenameSessionRequest, Response,
9    SessionName, SwitchClientExtRequest, SwitchClientRequest, TerminalSize,
10};
11
12use crate::{
13    connection::{AttachTransition, Connection},
14    ClientError,
15};
16
17impl Connection {
18    /// Sends a `new-session` request over the detached RPC channel.
19    pub fn new_session(
20        &mut self,
21        session_name: SessionName,
22        detached: bool,
23        size: Option<TerminalSize>,
24    ) -> Result<Response, ClientError> {
25        self.new_session_with_environment(session_name, detached, size, None)
26    }
27
28    /// Sends a `new-session` request with explicit spawn environment overrides.
29    pub fn new_session_with_environment(
30        &mut self,
31        session_name: SessionName,
32        detached: bool,
33        size: Option<TerminalSize>,
34        environment: Option<Vec<String>>,
35    ) -> Result<Response, ClientError> {
36        self.roundtrip(&Request::NewSession(NewSessionRequest {
37            session_name,
38            detached,
39            size,
40            environment,
41        }))
42    }
43
44    /// Sends an extended `new-session` request with grouped-session and attach-if-exists semantics.
45    pub fn new_session_extended(
46        &mut self,
47        request: NewSessionExtRequest,
48    ) -> Result<Response, ClientError> {
49        self.roundtrip(&Request::NewSessionExt(request))
50    }
51
52    /// Sends a `has-session` request over the detached RPC channel.
53    pub fn has_session(&mut self, target: SessionName) -> Result<Response, ClientError> {
54        self.roundtrip(&Request::HasSession(HasSessionRequest { target }))
55    }
56
57    /// Sends a `kill-session` request over the detached RPC channel.
58    pub fn kill_session(&mut self, request: KillSessionRequest) -> Result<Response, ClientError> {
59        self.roundtrip(&Request::KillSession(request))
60    }
61
62    /// Sends a `rename-session` request over the detached RPC channel.
63    pub fn rename_session(
64        &mut self,
65        target: SessionName,
66        new_name: SessionName,
67    ) -> Result<Response, ClientError> {
68        self.roundtrip(&Request::RenameSession(RenameSessionRequest {
69            target,
70            new_name,
71        }))
72    }
73
74    /// Sends a `list-sessions` request over the detached RPC channel.
75    pub fn list_sessions(&mut self, request: ListSessionsRequest) -> Result<Response, ClientError> {
76        self.roundtrip(&Request::ListSessions(request))
77    }
78
79    /// Sends a `list-panes` request over the detached RPC channel.
80    pub fn list_panes(
81        &mut self,
82        target: SessionName,
83        format: Option<String>,
84    ) -> Result<Response, ClientError> {
85        self.list_panes_in_window(target, None, format)
86    }
87
88    /// Sends a `list-panes` request scoped to an optional window index.
89    pub fn list_panes_in_window(
90        &mut self,
91        target: SessionName,
92        target_window_index: Option<u32>,
93        format: Option<String>,
94    ) -> Result<Response, ClientError> {
95        self.roundtrip(&Request::ListPanes(ListPanesRequest {
96            target,
97            target_window_index,
98            format,
99        }))
100    }
101
102    /// Sends a `switch-client` request over the detached RPC channel.
103    pub fn switch_client(&mut self, target: SessionName) -> Result<Response, ClientError> {
104        self.roundtrip(&Request::SwitchClient(SwitchClientRequest { target }))
105    }
106
107    /// Sends an extended `switch-client` request over the detached RPC channel.
108    pub fn switch_client_extended(
109        &mut self,
110        target: Option<SessionName>,
111        key_table: Option<String>,
112    ) -> Result<Response, ClientError> {
113        self.roundtrip(&Request::SwitchClientExt(SwitchClientExtRequest {
114            target,
115            key_table,
116        }))
117    }
118
119    /// Sends a further-extended `switch-client` request over the detached RPC channel.
120    pub fn switch_client_with_session_flags(
121        &mut self,
122        request: SwitchClientExt2Request,
123    ) -> Result<Response, ClientError> {
124        self.roundtrip(&Request::SwitchClientExt2(request))
125    }
126
127    /// Sends the most recent `switch-client` request shape over the detached RPC channel.
128    pub fn switch_client_with_target_selector(
129        &mut self,
130        request: SwitchClientExt3Request,
131    ) -> Result<Response, ClientError> {
132        self.roundtrip(&Request::SwitchClientExt3(request))
133    }
134
135    /// Sends a `detach-client` request over the detached RPC channel.
136    pub fn detach_client(&mut self) -> Result<Response, ClientError> {
137        self.roundtrip(&Request::DetachClient(DetachClientRequest))
138    }
139
140    /// Sends an extended `detach-client` request over the detached RPC channel.
141    pub fn detach_client_extended(
142        &mut self,
143        request: DetachClientExtRequest,
144    ) -> Result<Response, ClientError> {
145        self.roundtrip(&Request::DetachClientExt(request))
146    }
147
148    /// Sends a `refresh-client` request over the detached RPC channel.
149    pub fn refresh_client(
150        &mut self,
151        request: RefreshClientRequest,
152    ) -> Result<Response, ClientError> {
153        self.roundtrip(&Request::RefreshClient(request))
154    }
155
156    /// Sends a `list-clients` request over the detached RPC channel.
157    pub fn list_clients(&mut self, request: ListClientsRequest) -> Result<Response, ClientError> {
158        self.roundtrip(&Request::ListClients(request))
159    }
160
161    /// Sends a `suspend-client` request over the detached RPC channel.
162    pub fn suspend_client(
163        &mut self,
164        request: SuspendClientRequest,
165    ) -> Result<Response, ClientError> {
166        self.roundtrip(&Request::SuspendClient(request))
167    }
168
169    /// Requests an attach upgrade and, on success, yields the raw Unix stream.
170    ///
171    /// Once this method returns [`AttachTransition::Upgraded`], the detached
172    /// framing codec is no longer in the data path for the connection.
173    pub fn begin_attach(mut self, target: SessionName) -> Result<AttachTransition, ClientError> {
174        self.write_request(&Request::AttachSession(AttachSessionRequest { target }))?;
175        let response = self.read_response()?;
176
177        match response {
178            Response::AttachSession(response) => Ok(AttachTransition::Upgraded(
179                self.into_attach_upgrade(response)?,
180            )),
181            other => Ok(AttachTransition::Rejected(other)),
182        }
183    }
184
185    /// Requests an extended attach upgrade and, on success, yields the raw Unix stream.
186    pub fn begin_attach_extended(
187        mut self,
188        request: AttachSessionExtRequest,
189    ) -> Result<AttachTransition, ClientError> {
190        self.write_request(&Request::AttachSessionExt(request))?;
191        let response = self.read_response()?;
192
193        match response {
194            Response::AttachSession(response) => Ok(AttachTransition::Upgraded(
195                self.into_attach_upgrade(response)?,
196            )),
197            other => Ok(AttachTransition::Rejected(other)),
198        }
199    }
200
201    /// Sends the most recent `attach-session` request shape over the detached RPC channel.
202    pub fn begin_attach_with_target_spec(
203        mut self,
204        request: AttachSessionExt2Request,
205    ) -> Result<AttachTransition, ClientError> {
206        self.write_request(&Request::AttachSessionExt2(request))?;
207        let response = self.read_response()?;
208
209        match response {
210            Response::AttachSession(response) => Ok(AttachTransition::Upgraded(
211                self.into_attach_upgrade(response)?,
212            )),
213            other => Ok(AttachTransition::Rejected(other)),
214        }
215    }
216
217    /// Sends the most recent `attach-session` request shape over the detached RPC channel.
218    pub fn attach_session_with_target_spec_detached(
219        &mut self,
220        request: AttachSessionExt2Request,
221    ) -> Result<Response, ClientError> {
222        self.roundtrip(&Request::AttachSessionExt2(request))
223    }
224}