file_system.rs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. use crate::ApplicationDispatcherExt;
  2. use tauri_api::{dir, file, path::resolve_path};
  3. use std::{fs, fs::File, io::Write, path::PathBuf};
  4. use super::cmd::{DirOperationOptions, FileOperationOptions};
  5. /// Reads a directory.
  6. #[cfg(read_dir)]
  7. pub async fn read_dir<D: ApplicationDispatcherExt>(
  8. dispatcher: &mut D,
  9. path: PathBuf,
  10. options: Option<DirOperationOptions>,
  11. callback: String,
  12. error: String,
  13. ) {
  14. crate::execute_promise(
  15. dispatcher,
  16. async move {
  17. let (recursive, dir) = if let Some(options_value) = options {
  18. (options_value.recursive, options_value.dir)
  19. } else {
  20. (false, None)
  21. };
  22. dir::read_dir(resolve_path(path, dir)?, recursive).map_err(crate::Error::FailedToExecuteApi)
  23. },
  24. callback,
  25. error,
  26. )
  27. .await;
  28. }
  29. /// Copies a file.
  30. #[cfg(copy_file)]
  31. pub async fn copy_file<D: ApplicationDispatcherExt>(
  32. dispatcher: &mut D,
  33. source: PathBuf,
  34. destination: PathBuf,
  35. options: Option<FileOperationOptions>,
  36. callback: String,
  37. error: String,
  38. ) {
  39. crate::execute_promise(
  40. dispatcher,
  41. async move {
  42. let (src, dest) = match options.and_then(|o| o.dir) {
  43. Some(dir) => (
  44. resolve_path(source, Some(dir.clone()))?,
  45. resolve_path(destination, Some(dir))?,
  46. ),
  47. None => (source, destination),
  48. };
  49. fs::copy(src, dest)?;
  50. crate::Result::Ok(())
  51. },
  52. callback,
  53. error,
  54. )
  55. .await;
  56. }
  57. /// Creates a directory.
  58. #[cfg(create_dir)]
  59. pub async fn create_dir<D: ApplicationDispatcherExt>(
  60. dispatcher: &mut D,
  61. path: PathBuf,
  62. options: Option<DirOperationOptions>,
  63. callback: String,
  64. error: String,
  65. ) {
  66. crate::execute_promise(
  67. dispatcher,
  68. async move {
  69. let (recursive, dir) = if let Some(options_value) = options {
  70. (options_value.recursive, options_value.dir)
  71. } else {
  72. (false, None)
  73. };
  74. let resolved_path = resolve_path(path, dir)?;
  75. if recursive {
  76. fs::create_dir_all(resolved_path)?;
  77. } else {
  78. fs::create_dir(resolved_path)?;
  79. }
  80. crate::Result::Ok(())
  81. },
  82. callback,
  83. error,
  84. )
  85. .await;
  86. }
  87. /// Removes a directory.
  88. #[cfg(remove_dir)]
  89. pub async fn remove_dir<D: ApplicationDispatcherExt>(
  90. dispatcher: &mut D,
  91. path: PathBuf,
  92. options: Option<DirOperationOptions>,
  93. callback: String,
  94. error: String,
  95. ) {
  96. crate::execute_promise(
  97. dispatcher,
  98. async move {
  99. let (recursive, dir) = if let Some(options_value) = options {
  100. (options_value.recursive, options_value.dir)
  101. } else {
  102. (false, None)
  103. };
  104. let resolved_path = resolve_path(path, dir)?;
  105. if recursive {
  106. fs::remove_dir_all(resolved_path)?;
  107. } else {
  108. fs::remove_dir(resolved_path)?;
  109. }
  110. crate::Result::Ok(())
  111. },
  112. callback,
  113. error,
  114. )
  115. .await;
  116. }
  117. /// Removes a file
  118. #[cfg(remove_file)]
  119. pub async fn remove_file<D: ApplicationDispatcherExt>(
  120. dispatcher: &mut D,
  121. path: PathBuf,
  122. options: Option<FileOperationOptions>,
  123. callback: String,
  124. error: String,
  125. ) {
  126. crate::execute_promise(
  127. dispatcher,
  128. async move {
  129. let resolved_path = resolve_path(path, options.and_then(|o| o.dir))?;
  130. fs::remove_file(resolved_path)?;
  131. crate::Result::Ok(())
  132. },
  133. callback,
  134. error,
  135. )
  136. .await;
  137. }
  138. /// Renames a file.
  139. #[cfg(rename_file)]
  140. pub async fn rename_file<D: ApplicationDispatcherExt>(
  141. dispatcher: &mut D,
  142. old_path: PathBuf,
  143. new_path: PathBuf,
  144. options: Option<FileOperationOptions>,
  145. callback: String,
  146. error: String,
  147. ) {
  148. crate::execute_promise(
  149. dispatcher,
  150. async move {
  151. let (old, new) = match options.and_then(|o| o.dir) {
  152. Some(dir) => (
  153. resolve_path(old_path, Some(dir.clone()))?,
  154. resolve_path(new_path, Some(dir))?,
  155. ),
  156. None => (old_path, new_path),
  157. };
  158. fs::rename(old, new).map_err(crate::Error::Io)
  159. },
  160. callback,
  161. error,
  162. )
  163. .await;
  164. }
  165. /// Writes a text file.
  166. #[cfg(write_file)]
  167. pub async fn write_file<D: ApplicationDispatcherExt>(
  168. dispatcher: &mut D,
  169. path: PathBuf,
  170. contents: String,
  171. options: Option<FileOperationOptions>,
  172. callback: String,
  173. error: String,
  174. ) {
  175. crate::execute_promise(
  176. dispatcher,
  177. async move {
  178. File::create(resolve_path(path, options.and_then(|o| o.dir))?)
  179. .map_err(crate::Error::Io)
  180. .and_then(|mut f| f.write_all(contents.as_bytes()).map_err(|err| err.into()))?;
  181. crate::Result::Ok(())
  182. },
  183. callback,
  184. error,
  185. )
  186. .await;
  187. }
  188. /// Writes a binary file.
  189. #[cfg(write_binary_file)]
  190. pub async fn write_binary_file<D: ApplicationDispatcherExt>(
  191. dispatcher: &mut D,
  192. path: PathBuf,
  193. contents: String,
  194. options: Option<FileOperationOptions>,
  195. callback: String,
  196. error: String,
  197. ) {
  198. crate::execute_promise(
  199. dispatcher,
  200. async move {
  201. base64::decode(contents)
  202. .map_err(crate::Error::Base64Decode)
  203. .and_then(|c| {
  204. File::create(resolve_path(path, options.and_then(|o| o.dir))?)
  205. .map_err(|e| e.into())
  206. .and_then(|mut f| f.write_all(&c).map_err(|err| err.into()))
  207. })?;
  208. crate::Result::Ok(())
  209. },
  210. callback,
  211. error,
  212. )
  213. .await;
  214. }
  215. /// Reads a text file.
  216. #[cfg(read_text_file)]
  217. pub async fn read_text_file<D: ApplicationDispatcherExt>(
  218. dispatcher: &mut D,
  219. path: PathBuf,
  220. options: Option<FileOperationOptions>,
  221. callback: String,
  222. error: String,
  223. ) {
  224. crate::execute_promise(
  225. dispatcher,
  226. async move {
  227. file::read_string(resolve_path(path, options.and_then(|o| o.dir))?)
  228. .map_err(crate::Error::FailedToExecuteApi)
  229. },
  230. callback,
  231. error,
  232. )
  233. .await;
  234. }
  235. /// Reads a binary file.
  236. #[cfg(read_binary_file)]
  237. pub async fn read_binary_file<D: ApplicationDispatcherExt>(
  238. dispatcher: &mut D,
  239. path: PathBuf,
  240. options: Option<FileOperationOptions>,
  241. callback: String,
  242. error: String,
  243. ) {
  244. crate::execute_promise(
  245. dispatcher,
  246. async move {
  247. file::read_binary(resolve_path(path, options.and_then(|o| o.dir))?)
  248. .map_err(crate::Error::FailedToExecuteApi)
  249. },
  250. callback,
  251. error,
  252. )
  253. .await;
  254. }
  255. // test webview functionality.
  256. #[cfg(test)]
  257. mod test {
  258. // use super::*;
  259. // use web_view::*;
  260. // create a makeshift webview
  261. // fn create_test_webview() -> crate::Result<WebView<'static, ()>> {
  262. // // basic html set into webview
  263. // let content = r#"<html><head></head><body></body></html>"#;
  264. // Ok(
  265. // // use webview builder to create simple webview
  266. // WebViewBuilder::new()
  267. // .title("test")
  268. // .size(800, 800)
  269. // .resizable(true)
  270. // .debug(true)
  271. // .user_data(())
  272. // .invoke_handler(|_wv, _arg| Ok(()))
  273. // .content(Content::Html(content))
  274. // .build()?,
  275. // )
  276. // }
  277. /* #[test]
  278. #[cfg(not(any(target_os = "linux", target_os = "macos")))]
  279. // test the file_write functionality
  280. fn test_write_to_file() -> crate::Result<()> {
  281. // import read_to_string and write to be able to manipulate the file.
  282. use std::fs::{read_to_string, write};
  283. // create the webview
  284. let mut webview = create_test_webview()?;
  285. // setup the contents and the path.
  286. let contents = String::from(r#"Write to the Test file"#);
  287. let path = String::from("test/fixture/test.txt");
  288. // clear the file by writing nothing to it.
  289. write(&path, "")?;
  290. //call write file with the path and contents.
  291. write_file(
  292. &mut dispatcher,
  293. path.clone(),
  294. contents.clone(),
  295. String::from(""),
  296. String::from(""),
  297. );
  298. // sleep the main thread to wait for the promise to execute.
  299. std::thread::sleep(std::time::Duration::from_millis(200));
  300. // read from the file.
  301. let data = read_to_string(path)?;
  302. // check that the file contents is equal to the expected contents.
  303. assert_eq!(data, contents);
  304. Ok(())
  305. } */
  306. }