mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-01 10:01:07 +02:00
feat(tauri) extend file system API (#512)
* feat(tauri) extend file system API * chore(deps) pin web-view deps
This commit is contained in:
committed by
GitHub
parent
37e8e79a04
commit
8ac066700a
@@ -51,9 +51,71 @@ function readDir (dir, options = {}) {
|
||||
return tauri.readDir(dir, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a directory
|
||||
* If one of the path's parent components doesn't exist and the `recursive` option isn't set to true, it will be rejected
|
||||
*
|
||||
* @param {string} dir path to the directory to create
|
||||
* @param {object} [options] configuration object
|
||||
* @param {boolean} [options.recursive] whether to create the directory's parent components or not
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function createDir (dir, options = {}) {
|
||||
return tauri.createDir(dir, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a directory
|
||||
* If the directory is not empty and the `recursive` option isn't set to true, it will be rejected
|
||||
*
|
||||
* @param {string} dir path to the directory to remove
|
||||
* @param {object} [options] configuration object
|
||||
* @param {boolean} [options.recursive] whether to remove all of the directory's content or not
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function removeDir (dir, options = {}) {
|
||||
return tauri.removeDir(dir, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy file
|
||||
*
|
||||
* @param {string} source
|
||||
* @param {string} destination
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function copyFile (source, destination) {
|
||||
return tauri.copyFile(source, destination)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a file
|
||||
*
|
||||
* @param {string} file path to the file to remove
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function removeFile (file) {
|
||||
return tauri.removeFile(file)
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a file
|
||||
*
|
||||
* @param {string} oldPath
|
||||
* @param {string} newPath
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function renameFile (oldPath, newPath) {
|
||||
return tauri.renameFile(oldPath, newPath)
|
||||
}
|
||||
|
||||
export {
|
||||
readTextFile,
|
||||
readBinaryFile,
|
||||
writeFile,
|
||||
readDir
|
||||
readDir,
|
||||
createDir,
|
||||
removeDir,
|
||||
copyFile,
|
||||
removeFile
|
||||
}
|
||||
|
||||
@@ -306,6 +306,130 @@ window.tauri = {
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name createDir
|
||||
* @description Creates a directory
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {Boolean} [options.recursive]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
createDir: function createDir(path, options) {
|
||||
<% if (tauri.whitelist.createDir === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'createDir',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('createDir')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name removeDir
|
||||
* @description Removes a directory
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {Boolean} [options.recursive]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
removeDir: function removeDir(path, options) {
|
||||
<% if (tauri.whitelist.removeDir === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'removeDir',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('removeDir')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name copyFile
|
||||
* @description Copy file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} source
|
||||
* @param {String} destination
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
copyFile: function copyFile(source, destination) {
|
||||
<% if (tauri.whitelist.copyFile === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'copyFile',
|
||||
source: source,
|
||||
destination: destination
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('copyFile')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name removeFile
|
||||
* @description Removes a file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
removeFile: function removeFile(path) {
|
||||
<% if (tauri.whitelist.removeFile === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'removeFile',
|
||||
path: path
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('removeFile')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name renameFile
|
||||
* @description Renames a file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
<% } %>
|
||||
renameFile: function renameFile(oldPath, newPath) {
|
||||
<% if (tauri.whitelist.renameFile === true || tauri.whitelist.all === true) { %>
|
||||
return this.promisified({
|
||||
cmd: 'renameFile',
|
||||
old_path: oldPath,
|
||||
new_path: newPath
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('renameFile')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name setTitle
|
||||
|
||||
@@ -44,7 +44,7 @@ pub fn walk_dir(path_copy: String) -> crate::Result<Vec<DiskEntry>> {
|
||||
|
||||
pub fn list_dir_contents(dir_path: String) -> crate::Result<Vec<DiskEntry>> {
|
||||
fs::read_dir(dir_path)
|
||||
.map_err(|err| crate::Error::with_chain(err, "read string failed"))
|
||||
.map_err(|err| crate::Error::with_chain(err, "read dir failed"))
|
||||
.and_then(|paths| {
|
||||
let mut dirs: Vec<DiskEntry> = vec![];
|
||||
for path in paths {
|
||||
|
||||
@@ -12,7 +12,8 @@ exclude = ["test/fixture/**"]
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
web-view = "0.6.0"
|
||||
webview-sys = "=0.4.0"
|
||||
web-view = "=0.6.0"
|
||||
tauri_includedir = "0.5.0"
|
||||
phf = "0.8.0"
|
||||
base64 = "0.12.0"
|
||||
@@ -44,6 +45,11 @@ read-text-file = []
|
||||
read-binary-file = []
|
||||
write-file = []
|
||||
read-dir = []
|
||||
copy-file = []
|
||||
create-dir = []
|
||||
remove-dir = []
|
||||
remove-file = []
|
||||
rename-file = []
|
||||
set-title = []
|
||||
execute = []
|
||||
open = []
|
||||
|
||||
@@ -277,6 +277,105 @@ window.tauri = {
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name createDir
|
||||
* @description Creates a directory
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {Boolean} [options.recursive]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
createDir: function createDir(path, options) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'createDir',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name removeDir
|
||||
* @description Removes a directory
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {Boolean} [options.recursive]
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
removeDir: function removeDir(path, options) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'removeDir',
|
||||
path: path,
|
||||
options: options
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name copyFile
|
||||
* @description Copy file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} source
|
||||
* @param {String} destination
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
copyFile: function copyFile(source, destination) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'copyFile',
|
||||
source: source,
|
||||
destination: destination
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name removeFile
|
||||
* @description Removes a file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
removeFile: function removeFile(path) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'removeFile',
|
||||
path: path
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name renameFile
|
||||
* @description Renames a file
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {String} path
|
||||
* @returns {*|Promise<any>|Promise}
|
||||
*/
|
||||
|
||||
renameFile: function renameFile(oldPath, newPath) {
|
||||
|
||||
return this.promisified({
|
||||
cmd: 'renameFile',
|
||||
old_path: oldPath,
|
||||
new_path: newPath
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @name setTitle
|
||||
* @description Set the application's title
|
||||
|
||||
@@ -58,6 +58,50 @@ pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> cra
|
||||
} => {
|
||||
file_system::read_dir(webview, path, options, callback, error);
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "copy-file"))]
|
||||
CopyFile {
|
||||
source,
|
||||
destination,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
file_system::copy_file(webview, source, destination, callback, error);
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "create-dir"))]
|
||||
CreateDir {
|
||||
path,
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
file_system::create_dir(webview, path, options, callback, error);
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "remove-dir"))]
|
||||
RemoveDir {
|
||||
path,
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
file_system::remove_dir(webview, path, options, callback, error);
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "remove-file"))]
|
||||
RemoveFile {
|
||||
path,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
file_system::remove_file(webview, path, callback, error);
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "rename-file"))]
|
||||
RenameFile {
|
||||
old_path,
|
||||
new_path,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
file_system::rename_file(webview, old_path, new_path, callback, error);
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "set-title"))]
|
||||
SetTitle { title } => {
|
||||
webview.set_title(&title)?;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ReadDirOptions {
|
||||
pub struct DirOperationOptions {
|
||||
#[serde(default)]
|
||||
pub recursive: bool
|
||||
}
|
||||
@@ -48,7 +48,41 @@ pub enum Cmd {
|
||||
#[cfg(any(feature = "all-api", feature = "read-dir"))]
|
||||
ReadDir {
|
||||
path: String,
|
||||
options: Option<ReadDirOptions>,
|
||||
options: Option<DirOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "copy-file"))]
|
||||
CopyFile {
|
||||
source: String,
|
||||
destination: String,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "create-dir"))]
|
||||
CreateDir {
|
||||
path: String,
|
||||
options: Option<DirOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "remove-dir"))]
|
||||
RemoveDir {
|
||||
path: String,
|
||||
options: Option<DirOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "remove-file"))]
|
||||
RemoveFile {
|
||||
path: String,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "rename-file"))]
|
||||
RenameFile {
|
||||
old_path: String,
|
||||
new_path: String,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
|
||||
@@ -3,15 +3,16 @@ use web_view::WebView;
|
||||
use tauri_api::dir;
|
||||
use tauri_api::file;
|
||||
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
|
||||
use super::cmd::{ReadDirOptions};
|
||||
use super::cmd::{DirOperationOptions};
|
||||
|
||||
pub fn read_dir<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
path: String,
|
||||
options: Option<ReadDirOptions>,
|
||||
options: Option<DirOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
) {
|
||||
@@ -25,11 +26,11 @@ pub fn read_dir<T: 'static>(
|
||||
};
|
||||
if recursive {
|
||||
dir::walk_dir(path)
|
||||
.map_err(|e| crate::ErrorKind::Command(e.to_string()).into())
|
||||
.map_err(|e| crate::ErrorKind::FileSystem(e.to_string()).into())
|
||||
.and_then(|f| serde_json::to_string(&f).map_err(|err| err.into()))
|
||||
} else {
|
||||
dir::list_dir_contents(path)
|
||||
.map_err(|e| crate::ErrorKind::Command(e.to_string()).into())
|
||||
.map_err(|e| crate::ErrorKind::FileSystem(e.to_string()).into())
|
||||
.and_then(|f| serde_json::to_string(&f).map_err(|err| err.into()))
|
||||
}
|
||||
},
|
||||
@@ -38,6 +39,122 @@ pub fn read_dir<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
pub fn copy_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
source: String,
|
||||
destination: String,
|
||||
callback: String,
|
||||
error: String,
|
||||
) {
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
fs::copy(source, destination)
|
||||
.map_err(|e| crate::ErrorKind::FileSystem(e.to_string()).into())
|
||||
.map(|_| "".to_string())
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn create_dir<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
path: String,
|
||||
options: Option<DirOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
) {
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
let recursive = if let Some(options_value) = options {
|
||||
options_value.recursive
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let response = if recursive {
|
||||
fs::create_dir_all(path)
|
||||
} else {
|
||||
fs::create_dir(path)
|
||||
};
|
||||
|
||||
response
|
||||
.map_err(|e| crate::ErrorKind::FileSystem(e.to_string()).into())
|
||||
.map(|_| "".to_string())
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn remove_dir<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
path: String,
|
||||
options: Option<DirOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
) {
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
let recursive = if let Some(options_value) = options {
|
||||
options_value.recursive
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let response = if recursive {
|
||||
fs::remove_dir_all(path)
|
||||
} else {
|
||||
fs::remove_dir(path)
|
||||
};
|
||||
|
||||
response
|
||||
.map_err(|e| crate::ErrorKind::FileSystem(e.to_string()).into())
|
||||
.map(|_| "".to_string())
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn remove_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
path: String,
|
||||
callback: String,
|
||||
error: String,
|
||||
) {
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
fs::remove_file(path)
|
||||
.map_err(|e| crate::ErrorKind::FileSystem(e.to_string()).into())
|
||||
.map(|_| "".to_string())
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn rename_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
old_path: String,
|
||||
new_path: String,
|
||||
callback: String,
|
||||
error: String,
|
||||
) {
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
fs::rename(old_path, new_path)
|
||||
.map_err(|e| crate::ErrorKind::FileSystem(e.to_string()).into())
|
||||
.map(|_| "".to_string())
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn write_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
file: String,
|
||||
@@ -49,7 +166,7 @@ pub fn write_file<T: 'static>(
|
||||
webview,
|
||||
move || {
|
||||
File::create(file)
|
||||
.map_err(|e| crate::ErrorKind::Command(e.to_string()).into())
|
||||
.map_err(|e| crate::ErrorKind::FileSystem(e.to_string()).into())
|
||||
.and_then(|mut f| {
|
||||
f.write_all(contents.as_bytes())
|
||||
.map_err(|err| err.into())
|
||||
@@ -71,7 +188,7 @@ pub fn read_text_file<T: 'static>(
|
||||
webview,
|
||||
move || {
|
||||
file::read_string(path)
|
||||
.map_err(|e| crate::ErrorKind::Command(e.to_string()).into())
|
||||
.map_err(|e| crate::ErrorKind::FileSystem(e.to_string()).into())
|
||||
.and_then(|f| {
|
||||
serde_json::to_string(&f)
|
||||
.map_err(|err| err.into())
|
||||
@@ -92,7 +209,7 @@ pub fn read_binary_file<T: 'static>(
|
||||
webview,
|
||||
move || {
|
||||
file::read_binary(path)
|
||||
.map_err(|e| crate::ErrorKind::Command(e.to_string()).into())
|
||||
.map_err(|e| crate::ErrorKind::FileSystem(e.to_string()).into())
|
||||
.and_then(|f| {
|
||||
serde_json::to_string(&f)
|
||||
.map_err(|err| err.into())
|
||||
|
||||
@@ -42,6 +42,10 @@ error_chain! {
|
||||
description("Command Error")
|
||||
display("Command Error: '{}'", t)
|
||||
}
|
||||
FileSystem(t: String) {
|
||||
description("FileSystem Error")
|
||||
display("FileSystem Error: '{}'", t)
|
||||
}
|
||||
Dialog(t: String) {
|
||||
description("Dialog Error")
|
||||
display("Dialog Error: '{}'", t)
|
||||
|
||||
Reference in New Issue
Block a user