1use crate::error::LauncherError;
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3
4#[derive(Debug, Serialize, Deserialize)]
6pub struct JsonRpcRequest {
7 pub method: Method,
8 pub parameters: Vec<Option<String>>,
9 pub settings: serde_json::Value,
10 pub id: i32,
11 pub error: serde_json::Value,
12}
13
14#[derive(Debug)]
16pub enum Method {
17 Query,
19 ContextMenu,
21 Custom(String),
24}
25
26impl Serialize for Method {
28 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
29 where
30 S: Serializer,
31 {
32 match self {
33 Method::Query => serializer.serialize_str("query"),
34 Method::ContextMenu => serializer.serialize_str("context_menu"),
35 Method::Custom(s) => serializer.serialize_str(s),
36 }
37 }
38}
39
40impl<'de> Deserialize<'de> for Method {
42 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
43 where
44 D: Deserializer<'de>,
45 {
46 let s = String::deserialize(deserializer)?;
47 match s.as_str() {
48 "query" => Ok(Method::Query),
49 "context_menu" => Ok(Method::ContextMenu),
50 _ => Ok(Method::Custom(s)),
51 }
52 }
53}
54
55impl JsonRpcRequest {
56 pub fn from(argument: &String) -> Result<Self, LauncherError> {
58 let input = serde_json::from_str::<JsonRpcRequest>(argument)?;
59 Ok(input)
60 }
61
62 pub fn get_parameter(&self) -> String {
64 self.parameters[0].clone().unwrap_or("".to_string())
65 }
66
67 pub fn set_response(&self, response: JsonRpcResponse) -> Result<(), LauncherError> {
69 println!("{}", response.to_unicode_string()?);
70 Ok(())
71 }
72
73 pub fn set_simple_response<S: Into<String>>(
75 &self,
76 title: S,
77 sub_title: S,
78 icon_path: S,
79 action: Option<JsonRpcAction>,
80 ) -> Result<(), LauncherError> {
81 let mut query_data = JsonRpcResponse::new();
82 let item = JsonRpcResponseDataBuilder::new()
83 .title(title)
84 .sub_title(sub_title)
85 .icon_path(icon_path)
86 .json_rpcaction(action)
87 .build();
88
89 query_data.add_data(item);
90 let response = query_data.to_unicode_string().unwrap();
91 tracing::info!("simple_response响应数据: {}", response);
92
93 println!("{}", response);
94 Ok(())
95 }
96
97 pub fn to_string(&self) -> Result<String, LauncherError> {
99 Ok(serde_json::to_string(&self)?)
100 }
101}
102
103#[derive(Debug, Serialize, Clone)]
107pub struct JsonRpcAction {
108 #[serde(rename = "method")]
109 pub method: String,
110 #[serde(rename = "parameters")]
111 pub parameters: Vec<String>,
112}
113
114impl JsonRpcAction {
115 pub fn custom<S: Into<String>>(method: S, parameters: Vec<S>) -> Self {
118 Self {
119 method: method.into(),
120 parameters: parameters.into_iter().map(|s| s.into()).collect(),
121 }
122 }
123
124 pub fn change_query<S: Into<String>>(query: S, requery: bool) -> Self {
127 Self {
128 method: "Flow.Launcher.ChangeQuery".to_string(),
129 parameters: vec![query.into(), requery.to_string()],
130 }
131 }
132
133 pub fn restart_app() -> Self {
136 Self {
137 method: "Flow.Launcher.RestartApp".to_string(),
138 parameters: vec![],
139 }
140 }
141
142 pub fn close_app() -> Self {
144 Self {
145 method: "Flow.Launcher.CloseApp".to_string(),
146 parameters: vec![],
147 }
148 }
149
150 pub fn save_app_all_setings() -> Self {
153 Self {
154 method: "Flow.Launcher.SaveAppAllSettings".to_string(),
155 parameters: vec![],
156 }
157 }
158
159 pub fn check_for_new_update() -> Self {
161 Self {
162 method: "Flow.Launcher.CheckForNewUpdate".to_string(),
163 parameters: vec![],
164 }
165 }
166
167 pub fn shell_run<S: Into<String>>(cmd: S) -> Self {
170 Self {
171 method: "Flow.Launcher.ShellRun".to_string(),
172 parameters: vec![cmd.into()],
173 }
174 }
175
176 pub fn hide_app() -> Self {
178 Self {
179 method: "Flow.Launcher.HideApp".to_string(),
180 parameters: vec![],
181 }
182 }
183
184 pub fn show_app() -> Self {
186 Self {
187 method: "Flow.Launcher.ShowApp".to_string(),
188 parameters: vec![],
189 }
190 }
191
192 pub fn show_msg<S: Into<String>>(title: S, sub_title: S, ico_path: S) -> Self {
195 Self {
196 method: "Flow.Launcher.ShowMsg".to_string(),
197 parameters: vec![title.into(), sub_title.into(), ico_path.into()],
198 }
199 }
200
201 pub fn get_translation() -> Self {
203 Self {
204 method: "Flow.Launcher.GetTranslation".to_string(),
205 parameters: vec![],
206 }
207 }
208 pub fn open_setting_dialog() -> Self {
210 Self {
211 method: "Flow.Launcher.OpenSettingDialog".to_string(),
212 parameters: vec![],
213 }
214 }
215
216 pub fn get_all_plugins() -> Self {
218 Self {
219 method: "Flow.Launcher.GetAllPlugins".to_string(),
220 parameters: vec![],
221 }
222 }
223
224 pub fn start_loading_bar() -> Self {
226 Self {
227 method: "Flow.Launcher.StartLoadingBar".to_string(),
228 parameters: vec![],
229 }
230 }
231
232 pub fn stop_loading_bar() -> Self {
234 Self {
235 method: "Flow.Launcher.StopLoadingBar".to_string(),
236 parameters: vec![],
237 }
238 }
239
240 pub fn reload_all_plugin_data() -> Self {
242 Self {
243 method: "Flow.Launcher.ReloadAllPluginData".to_string(),
244 parameters: vec![],
245 }
246 }
247}
248
249#[derive(Debug, Serialize)]
251pub struct JsonRpcResponseData {
252 #[serde(rename = "Title")]
253 pub title: String,
254 #[serde(rename = "SubTitle")]
255 pub sub_title: String,
256 #[serde(rename = "score")]
258 #[serde(skip_serializing_if = "Option::is_none")]
259 pub score: Option<i32>,
260 #[serde(rename = "IcoPath")]
261 pub ico_path: String,
262 #[serde(rename = "JsonRPCAction")]
263 #[serde(skip_serializing_if = "Option::is_none")]
264 pub json_rpcaction: Option<JsonRpcAction>,
265}
266
267#[derive(Debug, Serialize)]
269pub struct JsonRpcResponse {
270 #[serde(rename = "result")]
271 pub result: Vec<JsonRpcResponseData>,
272}
273
274impl JsonRpcResponse {
275 pub fn new() -> Self {
276 Self { result: Vec::new() }
277 }
278 pub fn add_data(&mut self, data: JsonRpcResponseData) {
280 self.result.push(data);
281 }
282
283 pub fn to_unicode_string(&self) -> Result<String, LauncherError> {
285 let data = serde_json::to_string(&self)?;
286 Ok(self.escape_non_ascii(&data))
287 }
288
289 fn escape_non_ascii(&self, s: &str) -> String {
291 let mut escaped = String::with_capacity(s.len());
292 for ch in s.chars() {
293 if ch.is_ascii() {
294 escaped.push(ch);
295 } else {
296 let code = ch as u32;
297 escaped.push_str(&format!("\\u{:04x}", code));
298 }
299 }
300 escaped
301 }
302}
303
304pub struct JsonRpcResponseDataBuilder {
306 pub title: String,
308 pub sub_title: String,
310 pub score: Option<i32>,
312 pub ico_path: String,
314 pub json_rpcaction: Option<JsonRpcAction>,
316}
317impl JsonRpcResponseDataBuilder {
318 pub fn new() -> JsonRpcResponseDataBuilder {
319 Self {
320 title: "".to_string(),
321 sub_title: "".to_string(),
322 score: None,
323 ico_path: "".to_string(),
324 json_rpcaction: None,
325 }
326 }
327 pub fn title<S: Into<String>>(mut self, title: S) -> Self {
329 self.title = title.into();
330 self
331 }
332
333 pub fn sub_title<S: Into<String>>(mut self, sub_title: S) -> Self {
335 self.sub_title = sub_title.into();
336 self
337 }
338
339 pub fn score(mut self, score: i32) -> Self {
341 self.score = Some(score);
342 self
343 }
344
345 pub fn icon_path<S: Into<String>>(mut self, ico_path: S) -> Self {
347 self.ico_path = ico_path.into();
348 self
349 }
350
351 pub fn json_rpcaction(mut self, json_rpcaction: Option<JsonRpcAction>) -> Self {
353 self.json_rpcaction = json_rpcaction;
354 self
355 }
356
357 pub fn build(&self) -> JsonRpcResponseData {
359 JsonRpcResponseData {
360 title: self.title.clone(),
361 sub_title: self.sub_title.clone(),
362 score: self.score,
363 ico_path: self.ico_path.clone(),
364 json_rpcaction: self.json_rpcaction.clone(),
365 }
366 }
367}