diff --git a/.changes/fix-fs-write-file-android.md b/.changes/fix-fs-write-file-android.md new file mode 100644 index 00000000..e83a03c2 --- /dev/null +++ b/.changes/fix-fs-write-file-android.md @@ -0,0 +1,5 @@ +--- +"fs": patch:bug +--- + +Fixes `writeFile` command implementation on Android. diff --git a/plugins/fs/src/commands.rs b/plugins/fs/src/commands.rs index 184d9526..c59706e1 100644 --- a/plugins/fs/src/commands.rs +++ b/plugins/fs/src/commands.rs @@ -13,6 +13,7 @@ use tauri::{ }; use std::{ + borrow::Cow, fs::File, io::{BufReader, Lines, Read, Write}, path::{Path, PathBuf}, @@ -105,6 +106,8 @@ pub enum CommandError { #[error(transparent)] Tauri(#[from] tauri::Error), #[error(transparent)] + Json(#[from] serde_json::Error), + #[error(transparent)] Io(#[from] std::io::Error), #[error(transparent)] UrlParseError(#[from] url::ParseError), @@ -910,25 +913,31 @@ pub async fn write_file( command_scope: CommandScope, request: tauri::ipc::Request<'_>, ) -> CommandResult<()> { - if let tauri::ipc::InvokeBody::Raw(data) = request.body() { - let path = request - .headers() - .get("path") - .ok_or_else(|| anyhow::anyhow!("missing file path").into()) - .and_then(|p| { - p.to_str() - .map_err(|e| anyhow::anyhow!("invalid path: {e}").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) - } else { - Err(anyhow::anyhow!("unexpected invoke body").into()) - } + 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| { + p.to_str() + .map_err(|e| anyhow::anyhow!("invalid path: {e}").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) } #[tauri::command]