endpoints.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Copyright 2019-2021 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. use crate::{
  5. hooks::{InvokeError, InvokeMessage, InvokeResolver},
  6. runtime::Runtime,
  7. Config, Invoke, PackageInfo, Window,
  8. };
  9. use serde::{Deserialize, Serialize};
  10. use serde_json::Value as JsonValue;
  11. use std::sync::Arc;
  12. mod app;
  13. mod cli;
  14. mod clipboard;
  15. mod dialog;
  16. mod event;
  17. #[allow(unused_imports)]
  18. mod file_system;
  19. mod global_shortcut;
  20. mod http;
  21. mod notification;
  22. mod operating_system;
  23. mod path;
  24. mod process;
  25. mod shell;
  26. mod window;
  27. /// The response for a JS `invoke` call.
  28. pub struct InvokeResponse {
  29. json: crate::Result<JsonValue>,
  30. }
  31. impl<T: Serialize> From<T> for InvokeResponse {
  32. fn from(value: T) -> Self {
  33. Self {
  34. json: serde_json::to_value(value).map_err(Into::into),
  35. }
  36. }
  37. }
  38. #[derive(Deserialize)]
  39. #[serde(tag = "module", content = "message")]
  40. enum Module {
  41. App(app::Cmd),
  42. Process(process::Cmd),
  43. Fs(file_system::Cmd),
  44. Os(operating_system::Cmd),
  45. Path(path::Cmd),
  46. Window(Box<window::Cmd>),
  47. Shell(shell::Cmd),
  48. Event(event::Cmd),
  49. Dialog(dialog::Cmd),
  50. Cli(cli::Cmd),
  51. Notification(notification::Cmd),
  52. Http(http::Cmd),
  53. GlobalShortcut(global_shortcut::Cmd),
  54. Clipboard(clipboard::Cmd),
  55. }
  56. impl Module {
  57. fn run<R: Runtime>(
  58. self,
  59. window: Window<R>,
  60. resolver: InvokeResolver<R>,
  61. config: Arc<Config>,
  62. package_info: PackageInfo,
  63. ) {
  64. match self {
  65. Self::App(cmd) => resolver.respond_async(async move {
  66. cmd
  67. .run(package_info)
  68. .and_then(|r| r.json)
  69. .map_err(InvokeError::from)
  70. }),
  71. Self::Process(cmd) => resolver
  72. .respond_async(async move { cmd.run().and_then(|r| r.json).map_err(InvokeError::from) }),
  73. Self::Fs(cmd) => resolver.respond_async(async move {
  74. cmd
  75. .run(config, &package_info)
  76. .and_then(|r| r.json)
  77. .map_err(InvokeError::from)
  78. }),
  79. Self::Path(cmd) => resolver.respond_async(async move {
  80. cmd
  81. .run(config, &package_info)
  82. .and_then(|r| r.json)
  83. .map_err(InvokeError::from)
  84. }),
  85. Self::Os(cmd) => resolver
  86. .respond_async(async move { cmd.run().and_then(|r| r.json).map_err(InvokeError::from) }),
  87. Self::Window(cmd) => resolver.respond_async(async move {
  88. cmd
  89. .run(window)
  90. .await
  91. .and_then(|r| r.json)
  92. .map_err(InvokeError::from)
  93. }),
  94. Self::Shell(cmd) => resolver.respond_async(async move {
  95. cmd
  96. .run(window)
  97. .and_then(|r| r.json)
  98. .map_err(InvokeError::from)
  99. }),
  100. Self::Event(cmd) => resolver.respond_async(async move {
  101. cmd
  102. .run(window)
  103. .and_then(|r| r.json)
  104. .map_err(InvokeError::from)
  105. }),
  106. Self::Dialog(cmd) => resolver.respond_async(async move {
  107. cmd
  108. .run(window)
  109. .and_then(|r| r.json)
  110. .map_err(InvokeError::from)
  111. }),
  112. Self::Cli(cmd) => {
  113. if let Some(cli_config) = config.tauri.cli.clone() {
  114. resolver.respond_async(async move {
  115. cmd
  116. .run(&cli_config)
  117. .and_then(|r| r.json)
  118. .map_err(InvokeError::from)
  119. })
  120. }
  121. }
  122. Self::Notification(cmd) => resolver.respond_closure(move || {
  123. cmd
  124. .run(window, config, &package_info)
  125. .and_then(|r| r.json)
  126. .map_err(InvokeError::from)
  127. }),
  128. Self::Http(cmd) => resolver.respond_async(async move {
  129. cmd
  130. .run()
  131. .await
  132. .and_then(|r| r.json)
  133. .map_err(InvokeError::from)
  134. }),
  135. Self::GlobalShortcut(cmd) => resolver.respond_async(async move {
  136. cmd
  137. .run(window)
  138. .and_then(|r| r.json)
  139. .map_err(InvokeError::from)
  140. }),
  141. Self::Clipboard(cmd) => resolver.respond_async(async move {
  142. cmd
  143. .run(window)
  144. .and_then(|r| r.json)
  145. .map_err(InvokeError::from)
  146. }),
  147. }
  148. }
  149. }
  150. pub(crate) fn handle<R: Runtime>(
  151. module: String,
  152. invoke: Invoke<R>,
  153. config: Arc<Config>,
  154. package_info: &PackageInfo,
  155. ) {
  156. let Invoke { message, resolver } = invoke;
  157. let InvokeMessage {
  158. mut payload,
  159. window,
  160. ..
  161. } = message;
  162. if let JsonValue::Object(ref mut obj) = payload {
  163. obj.insert("module".to_string(), JsonValue::String(module));
  164. }
  165. match serde_json::from_value::<Module>(payload) {
  166. Ok(module) => module.run(window, resolver, config, package_info.clone()),
  167. Err(e) => resolver.reject(e.to_string()),
  168. }
  169. }