From e0898c22a0b1a963d4367c6f0b0340b4d6026770 Mon Sep 17 00:00:00 2001 From: luaneko Date: Wed, 25 Jun 2025 10:40:36 +1000 Subject: [PATCH] Add basic fs lib --- Cargo.lock | 7 +++ crates/lb/Cargo.toml | 3 +- crates/lb/src/fs.rs | 32 ++++++++++++ crates/lb/src/lib.rs | 1 + crates/lb/src/runtime.lua | 5 ++ crates/lb/src/runtime.rs | 82 ++++++++++++++++++++++++++++++ crates/luaffi_impl/src/metatype.rs | 2 +- src/lib.rs | 1 + 8 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 crates/lb/src/fs.rs create mode 100644 crates/lb/src/runtime.lua create mode 100644 crates/lb/src/runtime.rs diff --git a/Cargo.lock b/Cargo.lock index 955ad21..14937aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -250,6 +250,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "camino" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" + [[package]] name = "cc" version = "1.2.27" @@ -789,6 +795,7 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" name = "lb" version = "0.1.0" dependencies = [ + "camino", "derive_more", "luaffi", "luaify", diff --git a/crates/lb/Cargo.toml b/crates/lb/Cargo.toml index 0fd129f..1d1bf7c 100644 --- a/crates/lb/Cargo.toml +++ b/crates/lb/Cargo.toml @@ -4,10 +4,11 @@ version = "0.1.0" edition = "2024" [dependencies] +camino = "1.1.10" derive_more = { version = "2.0.1", features = ["full"] } luaffi = { version = "0.1.0", path = "../luaffi" } luajit = { version = "0.1.0", path = "../luajit" } -tokio = { version = "1.45.1", features = ["rt", "time", "fs"] } +tokio = { version = "1.45.1", features = ["rt", "time", "fs", "net", "process", "signal"] } [dev-dependencies] luaify = { path = "../luaify" } diff --git a/crates/lb/src/fs.rs b/crates/lb/src/fs.rs new file mode 100644 index 0000000..ea4d7c5 --- /dev/null +++ b/crates/lb/src/fs.rs @@ -0,0 +1,32 @@ +//! The `lb:fs` module provides utilities for interacting with the file system asynchronously. +//! +//! See [`lb_libfs`] for items exported by this module. +use luaffi::{cdef, metatype}; +use std::io; +use tokio::fs; + +/// Items exported by the `lb:fs` module. +/// +/// This module can be obtained by calling `require` in Lua. +/// +/// ```lua +/// local fs = require("lb:fs"); +/// ``` +#[cdef] +pub struct lb_libfs; + +#[metatype] +impl lb_libfs { + #[new] + extern "Lua-C" fn new() -> Self { + Self + } + + pub extern "Lua" fn read(&self, path: string) -> string { + self.__read(path) + } + + async extern "Lua-C" fn __read(&self, path: &str) -> io::Result> { + fs::read(path).await + } +} diff --git a/crates/lb/src/lib.rs b/crates/lb/src/lib.rs index b7e63d1..fb45b5d 100644 --- a/crates/lb/src/lib.rs +++ b/crates/lb/src/lib.rs @@ -1,4 +1,5 @@ pub mod channel; +pub mod fs; pub mod net; pub mod runtime; pub mod task; diff --git a/crates/lb/src/runtime.lua b/crates/lb/src/runtime.lua new file mode 100644 index 0000000..b802fff --- /dev/null +++ b/crates/lb/src/runtime.lua @@ -0,0 +1,5 @@ +local task = require("lb:task") + +function spawn(f, ...) + return task:spawn(f, ...) +end diff --git a/crates/lb/src/runtime.rs b/crates/lb/src/runtime.rs new file mode 100644 index 0000000..b8cbe9c --- /dev/null +++ b/crates/lb/src/runtime.rs @@ -0,0 +1,82 @@ +use crate::{channel::lb_libchannel, fs::lb_libfs, net::lb_libnet, task::lb_libtask}; +use luaffi::{Registry, Type}; +use luajit::{Chunk, State}; +use std::fmt::Display; +use tokio::{ + task::{JoinHandle, LocalSet, futures::TaskLocalFuture, spawn_local}, + task_local, +}; + +#[derive(Debug, Default)] +pub struct Builder { + registry: Registry, +} + +impl Builder { + pub fn new() -> Self { + let mut registry = Registry::new(); + + registry + .preload::("lb:task") + .preload::("lb:channel") + .preload::("lb:fs") + .preload::("lb:net"); + + Self { registry } + } + + pub fn module(&mut self, name: impl Display) -> &mut Self { + self.registry.preload::(name); + self + } + + pub fn registry(&self) -> &Registry { + &self.registry + } + + pub fn build(&self) -> luajit::Result { + Ok(Runtime { + state: { + let mut s = State::new()?; + let mut chunk = Chunk::new(self.registry.done()); + chunk.extend(include_bytes!("./runtime.lua")); + s.eval(chunk.path("[luby]"), 0, 0)?; + s + }, + tasks: LocalSet::new(), + }) + } +} + +#[derive(Debug)] +pub struct Runtime { + state: State, + tasks: LocalSet, +} + +task_local! { + static STATE: State; +} + +impl Runtime { + pub fn spawn( + &self, + f: impl AsyncFnOnce(&mut State) -> T + 'static, + ) -> JoinHandle { + self.tasks + .spawn_local(async move { f(&mut STATE.with(|s| s.new_thread())).await }) + } +} + +pub fn spawn(f: impl AsyncFnOnce(&mut State) -> T + 'static) -> JoinHandle { + spawn_local(async move { f(&mut STATE.with(|s| s.new_thread())).await }) +} + +impl IntoFuture for Runtime { + type Output = (); + type IntoFuture = TaskLocalFuture; + + fn into_future(self) -> Self::IntoFuture { + STATE.scope(self.state, self.tasks) + } +} diff --git a/crates/luaffi_impl/src/metatype.rs b/crates/luaffi_impl/src/metatype.rs index ddab6a6..760ac06 100644 --- a/crates/luaffi_impl/src/metatype.rs +++ b/crates/luaffi_impl/src/metatype.rs @@ -4,7 +4,7 @@ use crate::utils::{ use proc_macro2::TokenStream; use quote::{ToTokens, format_ident, quote, quote_spanned}; use std::{collections::HashSet, fmt, iter}; -use syn::{ext::IdentExt, punctuated::Punctuated, spanned::Spanned, *}; +use syn::{ext::IdentExt, spanned::Spanned, *}; pub fn transform(mut imp: ItemImpl) -> Result { syn_assert!( diff --git a/src/lib.rs b/src/lib.rs index a30429c..25803d2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,2 @@ +pub use lb::fs; pub use lb::net;