use super::*;
use std::path::PathBuf;
use tokio::{
fs,
io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader},
};
pub struct FSFile {
pub file: fs::File,
}
impl From<fs::File> for FSFile {
fn from(value: fs::File) -> Self {
Self { file: value }
}
}
impl LuaUserData for FSFile {
fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
methods.add_async_method_mut("write", |_, mut this, data: String| async move {
this.file.write_all(data.as_bytes()).await?;
Ok(())
});
methods.add_async_method_mut("read_line", |_, this, _: ()| async move {
let mut buf = BufReader::new(this.file.try_clone().await?);
let mut str = String::new();
buf.read_line(&mut str).await?;
Ok(str.trim().to_owned())
});
methods.add_async_method_mut("read_all", |_, mut this, _: ()| async move {
let mut str = String::new();
this.file.read_to_string(&mut str).await?;
Ok(str)
});
methods.add_async_method_mut("flush", |_, mut this, _: ()| async move {
this.file.flush().await?;
Ok(())
});
methods.add_async_method_mut("is_symlink", |_, this, _: ()| async move {
Ok(this.file.metadata().await?.is_symlink())
});
methods.add_async_method_mut("is_file", |_, this, _: ()| async move {
Ok(this.file.metadata().await?.is_file())
});
}
}
pub struct FS;
impl Module for FS {
async fn load(&self, state: &mut State) -> Result<(), LuaError> {
let module = state.lua.create_table()?;
module.set(
"create",
state.lua.create_async_function(|_, path: PathBuf| async {
match fs::File::create(path).await {
Ok(f) => Ok(FSFile::from(f)),
Err(e) => Err(e.into()),
}
})?,
)?;
module.set(
"open",
state.lua.create_async_function(|_, path: PathBuf| async {
match fs::File::open(path).await {
Ok(f) => Ok(FSFile::from(f)),
Err(e) => Err(e.into()),
}
})?,
)?;
create_module(&state.lua, "autosway.fs", module)?;
Ok(())
}
}