file_system.rs 7.2 KB

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