1use serde::de::{self, MapAccess, SeqAccess, Visitor};
2use serde::{Deserialize, Deserializer, Serialize};
3
4use crate::{ProcessCommand, SessionName, TerminalSize};
5
6use super::compat::{compat_next_element, required_next};
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub struct NewSessionRequest {
11 pub session_name: SessionName,
13 pub detached: bool,
15 pub size: Option<TerminalSize>,
17 #[serde(default)]
19 pub environment: Option<Vec<String>>,
20}
21
22#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
24pub struct NewSessionExtRequest {
25 pub session_name: Option<SessionName>,
27 #[serde(default)]
29 pub working_directory: Option<String>,
30 pub detached: bool,
32 pub size: Option<TerminalSize>,
34 #[serde(default)]
36 pub environment: Option<Vec<String>>,
37 #[serde(default)]
39 pub group_target: Option<SessionName>,
40 #[serde(default)]
42 pub attach_if_exists: bool,
43 #[serde(default)]
45 pub detach_other_clients: bool,
46 #[serde(default)]
48 pub kill_other_clients: bool,
49 #[serde(default)]
51 pub flags: Option<Vec<String>>,
52 #[serde(default)]
54 pub window_name: Option<String>,
55 #[serde(default)]
57 pub print_session_info: bool,
58 #[serde(default)]
60 pub print_format: Option<String>,
61 #[serde(default)]
64 pub command: Option<Vec<String>>,
65 #[serde(default)]
67 pub process_command: Option<ProcessCommand>,
68 #[serde(default)]
70 pub client_environment: Option<Vec<String>>,
71 #[serde(default)]
73 pub skip_environment_update: bool,
74}
75
76impl<'de> Deserialize<'de> for NewSessionExtRequest {
77 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
78 where
79 D: Deserializer<'de>,
80 {
81 deserializer.deserialize_struct(
82 "NewSessionExtRequest",
83 &[
84 "session_name",
85 "working_directory",
86 "detached",
87 "size",
88 "environment",
89 "group_target",
90 "attach_if_exists",
91 "detach_other_clients",
92 "kill_other_clients",
93 "flags",
94 "window_name",
95 "print_session_info",
96 "print_format",
97 "command",
98 "process_command",
99 "client_environment",
100 "skip_environment_update",
101 ],
102 NewSessionExtRequestVisitor,
103 )
104 }
105}
106
107struct NewSessionExtRequestVisitor;
108
109impl<'de> Visitor<'de> for NewSessionExtRequestVisitor {
110 type Value = NewSessionExtRequest;
111
112 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 formatter.write_str("a new-session extended request")
114 }
115
116 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
117 where
118 A: SeqAccess<'de>,
119 {
120 let session_name = required_next(&mut seq, 0, &self)?;
121 let working_directory = required_next(&mut seq, 1, &self)?;
122 let detached = required_next(&mut seq, 2, &self)?;
123 let size = required_next(&mut seq, 3, &self)?;
124 let environment = required_next(&mut seq, 4, &self)?;
125 let group_target = required_next(&mut seq, 5, &self)?;
126 let attach_if_exists = required_next(&mut seq, 6, &self)?;
127 let detach_other_clients = required_next(&mut seq, 7, &self)?;
128 let kill_other_clients = required_next(&mut seq, 8, &self)?;
129 let flags = required_next(&mut seq, 9, &self)?;
130 let window_name = required_next(&mut seq, 10, &self)?;
131 let print_session_info = required_next(&mut seq, 11, &self)?;
132 let print_format = required_next(&mut seq, 12, &self)?;
133 let command = required_next(&mut seq, 13, &self)?;
134 let process_command = compat_next_element(&mut seq)?;
135 let client_environment = compat_next_element(&mut seq)?;
136 let skip_environment_update: bool = compat_next_element(&mut seq)?;
137
138 Ok(NewSessionExtRequest {
139 session_name,
140 working_directory,
141 detached,
142 size,
143 environment,
144 group_target,
145 attach_if_exists,
146 detach_other_clients,
147 kill_other_clients,
148 flags,
149 window_name,
150 print_session_info,
151 print_format,
152 command,
153 process_command,
154 client_environment,
155 skip_environment_update,
156 })
157 }
158
159 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
160 where
161 A: MapAccess<'de>,
162 {
163 let mut session_name = None;
164 let mut working_directory = None;
165 let mut detached = None;
166 let mut size = None;
167 let mut environment = None;
168 let mut group_target = None;
169 let mut attach_if_exists = None;
170 let mut detach_other_clients = None;
171 let mut kill_other_clients = None;
172 let mut flags = None;
173 let mut window_name = None;
174 let mut print_session_info = None;
175 let mut print_format = None;
176 let mut command = None;
177 let mut process_command = None;
178 let mut client_environment = None;
179 let mut skip_environment_update = None;
180
181 while let Some(key) = map.next_key::<String>()? {
182 match key.as_str() {
183 "session_name" => session_name = Some(map.next_value()?),
184 "working_directory" => working_directory = Some(map.next_value()?),
185 "detached" => detached = Some(map.next_value()?),
186 "size" => size = Some(map.next_value()?),
187 "environment" => environment = Some(map.next_value()?),
188 "group_target" => group_target = Some(map.next_value()?),
189 "attach_if_exists" => attach_if_exists = Some(map.next_value()?),
190 "detach_other_clients" => detach_other_clients = Some(map.next_value()?),
191 "kill_other_clients" => kill_other_clients = Some(map.next_value()?),
192 "flags" => flags = Some(map.next_value()?),
193 "window_name" => window_name = Some(map.next_value()?),
194 "print_session_info" => print_session_info = Some(map.next_value()?),
195 "print_format" => print_format = Some(map.next_value()?),
196 "command" => command = Some(map.next_value()?),
197 "process_command" => process_command = Some(map.next_value()?),
198 "client_environment" => client_environment = Some(map.next_value()?),
199 "skip_environment_update" => skip_environment_update = Some(map.next_value()?),
200 _ => {
201 let _: de::IgnoredAny = map.next_value()?;
202 }
203 }
204 }
205
206 Ok(NewSessionExtRequest {
207 session_name: session_name.unwrap_or_default(),
208 working_directory: working_directory.unwrap_or_default(),
209 detached: detached.ok_or_else(|| de::Error::missing_field("detached"))?,
210 size: size.unwrap_or_default(),
211 environment: environment.unwrap_or_default(),
212 group_target: group_target.unwrap_or_default(),
213 attach_if_exists: attach_if_exists.unwrap_or_default(),
214 detach_other_clients: detach_other_clients.unwrap_or_default(),
215 kill_other_clients: kill_other_clients.unwrap_or_default(),
216 flags: flags.unwrap_or_default(),
217 window_name: window_name.unwrap_or_default(),
218 print_session_info: print_session_info.unwrap_or_default(),
219 print_format: print_format.unwrap_or_default(),
220 command: command.unwrap_or_default(),
221 process_command: process_command.unwrap_or_default(),
222 client_environment: client_environment.unwrap_or_default(),
223 skip_environment_update: skip_environment_update.unwrap_or_default(),
224 })
225 }
226}
227
228#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
230pub struct HasSessionRequest {
231 pub target: SessionName,
233}
234
235#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
237pub struct KillSessionRequest {
238 pub target: SessionName,
240 #[serde(default)]
242 pub kill_all_except_target: bool,
243 #[serde(default)]
245 pub clear_alerts: bool,
246 #[serde(default)]
248 pub kill_group: bool,
249}
250
251#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
253pub struct CreateSessionLeaseRequest {
254 pub session_name: SessionName,
256 pub ttl_millis: u64,
258}
259
260#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
262pub struct RenewSessionLeaseRequest {
263 pub session_name: SessionName,
265 pub token: u64,
267 pub ttl_millis: u64,
269}
270
271#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
273pub struct ReleaseSessionLeaseRequest {
274 pub session_name: SessionName,
276 pub token: u64,
278}
279
280#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
282pub struct RenameSessionRequest {
283 pub target: SessionName,
285 pub new_name: SessionName,
287}
288
289#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
291pub struct ListSessionsRequest {
292 pub format: Option<String>,
294 #[serde(default)]
296 pub filter: Option<String>,
297 #[serde(default)]
299 pub sort_order: Option<String>,
300 #[serde(default)]
302 pub reversed: bool,
303}