improve `writeTextFile` performance

pull/1950/head
amrbashir 9 months ago
parent f972e11fe5
commit 61c54d6117
No known key found for this signature in database
GPG Key ID: BBD7A47A2003FF33

File diff suppressed because one or more lines are too long

@ -1068,10 +1068,13 @@ async function writeTextFile(
throw new TypeError('Must be a file URL.') throw new TypeError('Must be a file URL.')
} }
await invoke('plugin:fs|write_text_file', { const encoder = new TextEncoder()
path: path instanceof URL ? path.toString() : path,
data, await invoke('plugin:fs|write_text_file', encoder.encode(data), {
options headers: {
path: path instanceof URL ? path.toString() : path,
options: JSON.stringify(options)
}
}) })
} }

@ -9,7 +9,7 @@ use tauri::{
ipc::{CommandScope, GlobalScope}, ipc::{CommandScope, GlobalScope},
path::BaseDirectory, path::BaseDirectory,
utils::config::FsScope, utils::config::FsScope,
AppHandle, Manager, Resource, ResourceId, Runtime, Webview, Manager, Resource, ResourceId, Runtime, Webview,
}; };
use std::{ use std::{
@ -804,10 +804,34 @@ fn write_file_inner<R: Runtime>(
webview: Webview<R>, webview: Webview<R>,
global_scope: &GlobalScope<Entry>, global_scope: &GlobalScope<Entry>,
command_scope: &CommandScope<Entry>, command_scope: &CommandScope<Entry>,
path: SafeFilePath, request: tauri::ipc::Request<'_>,
data: &[u8],
options: Option<WriteFileOptions>,
) -> CommandResult<()> { ) -> CommandResult<()> {
let data = match request.body() {
tauri::ipc::InvokeBody::Raw(data) => Cow::Borrowed(data),
tauri::ipc::InvokeBody::Json(serde_json::Value::Array(data)) => Cow::Owned(
data.iter()
.flat_map(|v| v.as_number().and_then(|v| v.as_u64().map(|v| v as u8)))
.collect(),
),
_ => return Err(anyhow::anyhow!("unexpected invoke body").into()),
};
let path = request
.headers()
.get("path")
.ok_or_else(|| anyhow::anyhow!("missing file path").into())
.and_then(|p| {
percent_encoding::percent_decode(p.as_ref())
.decode_utf8()
.map_err(|_| anyhow::anyhow!("path is not a valid UTF-8").into())
})
.and_then(|p| SafeFilePath::from_str(&p).map_err(CommandError::from))?;
let options: Option<WriteFileOptions> = request
.headers()
.get("options")
.and_then(|p| p.to_str().ok())
.and_then(|opts| serde_json::from_str(opts).ok());
let (mut file, path) = resolve_file( let (mut file, path) = resolve_file(
&webview, &webview,
global_scope, global_scope,
@ -844,7 +868,7 @@ fn write_file_inner<R: Runtime>(
}, },
)?; )?;
file.write_all(data) file.write_all(&data)
.map_err(|e| { .map_err(|e| {
format!( format!(
"failed to write bytes to file at path: {} with error: {e}", "failed to write bytes to file at path: {} with error: {e}",
@ -861,52 +885,18 @@ pub async fn write_file<R: Runtime>(
command_scope: CommandScope<Entry>, command_scope: CommandScope<Entry>,
request: tauri::ipc::Request<'_>, request: tauri::ipc::Request<'_>,
) -> CommandResult<()> { ) -> CommandResult<()> {
let data = match request.body() { write_file_inner(webview, &global_scope, &command_scope, request)
tauri::ipc::InvokeBody::Raw(data) => Cow::Borrowed(data),
tauri::ipc::InvokeBody::Json(serde_json::Value::Array(data)) => Cow::Owned(
data.iter()
.flat_map(|v| v.as_number().and_then(|v| v.as_u64().map(|v| v as u8)))
.collect(),
),
_ => return Err(anyhow::anyhow!("unexpected invoke body").into()),
};
let path = request
.headers()
.get("path")
.ok_or_else(|| anyhow::anyhow!("missing file path").into())
.and_then(|p| {
percent_encoding::percent_decode(p.as_ref())
.decode_utf8()
.map_err(|_| anyhow::anyhow!("path is not a valid UTF-8").into())
})
.and_then(|p| SafeFilePath::from_str(&p).map_err(CommandError::from))?;
let options = request
.headers()
.get("options")
.and_then(|p| p.to_str().ok())
.and_then(|opts| serde_json::from_str(opts).ok());
write_file_inner(webview, &global_scope, &command_scope, path, &data, options)
} }
// TODO, in v3, remove this command and rely on `write_file` command only
#[tauri::command] #[tauri::command]
pub async fn write_text_file<R: Runtime>( pub async fn write_text_file<R: Runtime>(
#[allow(unused)] app: AppHandle<R>, webview: Webview<R>,
#[allow(unused)] webview: Webview<R>, global_scope: GlobalScope<Entry>,
#[allow(unused)] global_scope: GlobalScope<Entry>, command_scope: CommandScope<Entry>,
#[allow(unused)] command_scope: CommandScope<Entry>, request: tauri::ipc::Request<'_>,
path: SafeFilePath,
data: String,
#[allow(unused)] options: Option<WriteFileOptions>,
) -> CommandResult<()> { ) -> CommandResult<()> {
write_file_inner( write_file_inner(webview, &global_scope, &command_scope, request)
webview,
&global_scope,
&command_scope,
path,
data.as_bytes(),
options,
)
} }
#[tauri::command] #[tauri::command]

Loading…
Cancel
Save