From 7cf937145744d8c7a2a9fc53ddba485b3d32f7a5 Mon Sep 17 00:00:00 2001 From: hankertrix <91734413+hankertrix@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:40:30 +0800 Subject: [PATCH] Initial attempt at exposing the file and directory creation APIs --- yazi-plugin/src/fs/fs.rs | 92 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/yazi-plugin/src/fs/fs.rs b/yazi-plugin/src/fs/fs.rs index 46ada698..447dc63f 100644 --- a/yazi-plugin/src/fs/fs.rs +++ b/yazi-plugin/src/fs/fs.rs @@ -1,9 +1,40 @@ use globset::GlobBuilder; -use mlua::{ExternalError, ExternalResult, Function, IntoLua, IntoLuaMulti, Lua, MetaMethod, Table, Value}; +use mlua::{ + ExternalError, ExternalResult, Function, IntoLua, IntoLuaMulti, Lua, MetaMethod, Table, Value, +}; use tokio::fs; use yazi_fs::remove_dir_clean; -use crate::{Error, bindings::{Cast, Cha}, file::File, url::{Url, UrlRef}}; +use crate::{ + Error, + bindings::{Cast, Cha}, + file::File, + url::{Url, UrlRef}, +}; + +const READ: u8 = 1; +const WRITE: u8 = 2; +const APPEND: u8 = 4; +const TRUNCATE: u8 = 8; +const CREATE: u8 = 16; +const CREATE_NEW: u8 = 32; + +pub struct OpenOpts; + +impl OpenOpts { + pub fn install(lua: &Lua) -> mlua::Result<()> { + let open_options = lua.create_table_from([ + ("READ", READ), + ("WRITE", WRITE), + ("APPEND", APPEND), + ("TRUNCATE", TRUNCATE), + ("CREATE", CREATE), + ("CREATE_NEW", CREATE_NEW), + ])?; + + lua.globals().raw_set("OpenOpts", open_options) + } +} pub fn compose(lua: &Lua) -> mlua::Result { let index = lua.create_function(|lua, (ts, key): (Table, mlua::String)| { @@ -12,6 +43,7 @@ pub fn compose(lua: &Lua) -> mlua::Result
{ b"cha" => cha(lua)?, b"write" => write(lua)?, b"remove" => remove(lua)?, + b"create_dir" => create_dir(lua)?, b"read_dir" => read_dir(lua)?, b"unique_name" => unique_name(lua)?, _ => return Ok(Value::Nil), @@ -50,6 +82,50 @@ fn cha(lua: &Lua) -> mlua::Result { }) } +fn open(lua: &Lua) -> mlua::Result { + lua.create_async_function(|lua, (url, opts): (UrlRef, Option)| async move { + let given_options = opts.unwrap_or(READ as i64); + let given_options = given_options as u8; + let mut write_flag = false; + let mut requires_write = false; + let mut open_opts = fs::OpenOptions::new(); + + if given_options & READ != 0 { + open_opts.read(true); + } + if given_options & WRITE != 0 { + write_flag = true; + open_opts.write(true); + } + if given_options & APPEND != 0 { + open_opts.append(true); + } + if given_options & TRUNCATE != 0 { + requires_write = true; + open_opts.truncate(true); + } + if given_options & CREATE != 0 { + requires_write = true; + open_opts.create(true); + } + if given_options & CREATE_NEW != 0 { + requires_write = true; + open_opts.create_new(true); + } + + if requires_write && !write_flag { + open_opts.write(true); + } + + let result = open_opts.open(&*url).await; + + match result { + Ok(file) => (File::cast(&lua, file)?, Value::Nil).into_lua_multi(&lua), + Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua), + } + }) +} + fn write(lua: &Lua) -> mlua::Result { lua.create_async_function(|lua, (url, data): (UrlRef, mlua::String)| async move { match fs::write(&*url, data.as_bytes()).await { @@ -76,6 +152,18 @@ fn remove(lua: &Lua) -> mlua::Result { }) } +fn create_dir(lua: &Lua) -> mlua::Result { + lua.create_async_function(|lua, (dir, recursive): (UrlRef, Option)| async move { + let is_recursive = recursive.unwrap_or(false); + let result = + if is_recursive { fs::create_dir_all(&*dir).await } else { fs::create_dir(&*dir).await }; + match result { + Ok(_) => (true, Value::Nil).into_lua_multi(&lua), + Err(e) => (false, Error::Io(e)).into_lua_multi(&lua), + } + }) +} + fn read_dir(lua: &Lua) -> mlua::Result { lua.create_async_function(|lua, (dir, options): (UrlRef, Table)| async move { let glob = if let Ok(s) = options.raw_get::("glob") {