Implement API for moving / renaming files and / or directories

This commit is contained in:
Filip Tibell 2023-02-23 00:00:48 +01:00
parent eecffca741
commit 1fdc6d088c
No known key found for this signature in database
7 changed files with 94 additions and 5 deletions

View file

@ -13,10 +13,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Implemented a new task scheduler which resolves several long-standing issues:
- Issues with yielding across the c-call/metamethod boundary no longer occur when calling certain async APIs that Lune provides.
- Ordering of interleaved calls to `task.spawn/task.defer` is now completely deterministic, defer is now guaranteed to run last even in these cases.
- The minimum wait time possible when using `task.wait` and minimum delay time using `task.delay` are now much smaller, and only limited by the underlying OS implementation. For most systems this means `task.wait` and `task.delay` are now accurate down to about 5 milliseconds or less.
- Added a new function `fs.move` to move / rename a file or directory from one path to another.
### Changed
- Type definitions are now bundled as part of the Lune executable, meaning they no longer need to be downloaded.

View file

@ -1,3 +1,7 @@
export type FsWriteOptions = {
overwrite: boolean,
}
--[=[
@class fs
@ -124,6 +128,25 @@ declare fs: {
@return If the path is a directory or not
]=]
isDir: (path: string) -> boolean,
--[=[
@within fs
Moves a file or directory to a new path.
Throws an error if a file or directory already exists at the target path.
This can be bypassed by passing `true` as the third argument, or a table of options with `overwrite` set to `true.`
An error will be thrown in the following situations:
* The current process lacks permissions to read at `from` or `to`.
* The new path exists on a different mount point.
* Some other I/O error occurred.
@param from The path to move from
@param to The path to move to
@param overwriteOrOptions Options the target path, such as if should be overwritten if it already exists
]=]
move: (from: string, to: string, overwriteOrOptions: boolean | FsWriteOptions) -> (),
}
type NetMethod = "GET" | "POST" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "PATCH"

View file

@ -3,7 +3,7 @@ use std::path::{PathBuf, MAIN_SEPARATOR};
use mlua::prelude::*;
use tokio::fs;
use crate::lua::table::TableBuilder;
use crate::lua::{fs::FsWriteOptions, table::TableBuilder};
pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
TableBuilder::new(lua)?
@ -15,6 +15,7 @@ pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
.with_async_function("removeDir", fs_remove_dir)?
.with_async_function("isFile", fs_is_file)?
.with_async_function("isDir", fs_is_dir)?
.with_async_function("move", fs_move)?
.build_readonly()
}
@ -93,3 +94,27 @@ async fn fs_is_dir(_: &'static Lua, path: String) -> LuaResult<bool> {
Ok(false)
}
}
async fn fs_move(
_: &'static Lua,
(from, to, options): (String, String, FsWriteOptions),
) -> LuaResult<()> {
let path_from = PathBuf::from(from);
if !path_from.exists() {
return Err(LuaError::RuntimeError(format!(
"No file or directory exists at the path '{}'",
path_from.display()
)));
}
let path_to = PathBuf::from(to);
if !options.overwrite && path_to.exists() {
return Err(LuaError::RuntimeError(format!(
"A file or directory alreadys exists at the path '{}'",
path_to.display()
)));
}
fs::rename(path_from, path_to)
.await
.map_err(LuaError::external)?;
Ok(())
}

View file

@ -0,0 +1,3 @@
mod options;
pub use options::FsWriteOptions;

View file

@ -0,0 +1,30 @@
use mlua::prelude::*;
pub struct FsWriteOptions {
pub(crate) overwrite: bool,
}
impl<'lua> FromLua<'lua> for FsWriteOptions {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
Ok(match value {
LuaValue::Nil => Self { overwrite: false },
LuaValue::Boolean(b) => Self { overwrite: b },
LuaValue::Table(t) => {
let overwrite: Option<bool> = t.get("overwrite")?;
Self {
overwrite: overwrite.unwrap_or(false),
}
}
_ => {
return Err(LuaError::FromLuaConversionError {
from: value.type_name(),
to: "FsWriteOptions",
message: Some(format!(
"Invalid write options - expected boolean or table, got {}",
value.type_name()
)),
})
}
})
}
}

View file

@ -1,6 +1,7 @@
mod create;
pub mod async_ext;
pub mod fs;
pub mod net;
pub mod process;
pub mod stdio;

View file

@ -79,10 +79,14 @@ impl<'lua> FromLua<'lua> for RequestConfig<'lua> {
});
};
// Anything else is invalid
Err(LuaError::RuntimeError(format!(
"Invalid request config - expected string or table, got {}",
value.type_name()
)))
Err(LuaError::FromLuaConversionError {
from: value.type_name(),
to: "RequestConfig",
message: Some(format!(
"Invalid request config - expected string or table, got {}",
value.type_name()
)),
})
}
}