Compare commits

..

No commits in common. "3a7f2366e463bfb93a7b30988c087b195d99f143" and "40829cdfc61696ca11b16c0d421556a1c04db7a7" have entirely different histories.

8 changed files with 29 additions and 212 deletions

20
Cargo.lock generated
View File

@ -579,12 +579,6 @@ dependencies = [
"windows-sys 0.60.2", "windows-sys 0.60.2",
] ]
[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.1.2" version = "1.1.2"
@ -1055,7 +1049,6 @@ dependencies = [
"luaffi", "luaffi",
"luajit", "luajit",
"sysexits", "sysexits",
"tempfile",
"thiserror", "thiserror",
"tokio", "tokio",
"walkdir", "walkdir",
@ -1739,19 +1732,6 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "198f60d1f7f003f168507691e42d082df109ef0f05c6fd006e22528371a5f1b4" checksum = "198f60d1f7f003f168507691e42d082df109ef0f05c6fd006e22528371a5f1b4"
[[package]]
name = "tempfile"
version = "3.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
dependencies = [
"fastrand",
"getrandom 0.3.3",
"once_cell",
"rustix",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "2.0.12" version = "2.0.12"

View File

@ -1,3 +1,7 @@
[jobs.test]
command = ["cargo", "test", "--workspace"]
need_stdout = true
[jobs.doc] [jobs.doc]
command = ["cargo", "doc", "--workspace"] command = ["cargo", "doc", "--workspace"]

View File

@ -9,7 +9,7 @@ repository.workspace = true
[features] [features]
task = ["tokio/rt", "tokio/time"] task = ["tokio/rt", "tokio/time"]
fs = ["tokio/fs", "dep:walkdir", "dep:globset", "dep:tempfile"] fs = ["tokio/fs", "dep:walkdir", "dep:globset"]
net = ["tokio/net"] net = ["tokio/net"]
[dependencies] [dependencies]
@ -18,7 +18,6 @@ globset = { version = "0.4.16", optional = true }
luaffi = { path = "../luaffi" } luaffi = { path = "../luaffi" }
luajit = { path = "../luajit" } luajit = { path = "../luajit" }
sysexits = "0.9.0" sysexits = "0.9.0"
tempfile = { version = "3.20.0", optional = true }
thiserror = "2.0.12" thiserror = "2.0.12"
tokio = { version = "1.45.1" } tokio = { version = "1.45.1" }
walkdir = { version = "2.5.0", optional = true } walkdir = { version = "2.5.0", optional = true }

View File

@ -98,14 +98,6 @@ impl lb_fslib {
prefix, prefix,
}) })
} }
pub extern "Lua-C" fn temp_dir(&self) -> Result<lb_temp_dir> {
Ok(tempfile::tempdir()?.into())
}
pub extern "Lua-C" fn temp_dir_in(&self, path: &str) -> Result<lb_temp_dir> {
Ok(tempfile::tempdir_in(path)?.into())
}
} }
/// Iterator over the entries in a directory. /// Iterator over the entries in a directory.
@ -409,20 +401,3 @@ impl lb_glob_dir {
Ok(None) Ok(None)
} }
} }
/// Directory in the filesystem that is automatically deleted when it is garbage-collected.
#[derive(Debug, From)]
#[cdef]
pub struct lb_temp_dir(#[opaque] tempfile::TempDir);
#[metatype]
impl lb_temp_dir {
pub extern "Lua-C" fn path(&self) -> String {
self.0.path().to_string_lossy().into()
}
#[tostring]
pub extern "Lua" fn tostring(&self) -> String {
self.path()
}
}

View File

@ -82,18 +82,18 @@ impl lb_netlib {
/// If `s` is an [`lb_ipaddr`], a copy of that value is returned. If `s` is an /// If `s` is an [`lb_ipaddr`], a copy of that value is returned. If `s` is an
/// [`lb_socketaddr`], the IP address part of the socket address is returned. Otherwise, parses /// [`lb_socketaddr`], the IP address part of the socket address is returned. Otherwise, parses
/// `s` as an IP address string. Both IPv4 or IPv6 addresses are supported. /// `s` as an IP address string. Both IPv4 or IPv6 addresses are supported.
pub extern "Lua" fn ipaddr(&self, addr: any) -> Result<lb_ipaddr> { pub extern "Lua" fn ipaddr(&self, s: any) -> Result<lb_ipaddr> {
if __istype(__ct.lb_ipaddr, addr) { if __istype(__ct.lb_ipaddr, s) {
__new(__ct.lb_ipaddr, addr) // copy constructor __new(__ct.lb_ipaddr, s) // copy constructor
} else if __istype(__ct.lb_socketaddr, addr) { } else if __istype(__ct.lb_socketaddr, s) {
s.ip() s.ip()
} else { } else {
self.__parse_ipaddr(addr) self.__parse_ipaddr(s)
} }
} }
extern "Lua-C" fn __parse_ipaddr(&self, addr: &str) -> Result<lb_ipaddr> { extern "Lua-C" fn __parse_ipaddr(&self, s: &str) -> Result<lb_ipaddr> {
Ok(addr.parse()?) Ok(s.parse()?)
} }
/// Creates an [`lb_socketaddr`] from the given input. /// Creates an [`lb_socketaddr`] from the given input.
@ -105,16 +105,16 @@ impl lb_netlib {
/// socket address string. Both IPv4 and IPv6 addresses are supported. /// socket address string. Both IPv4 and IPv6 addresses are supported.
/// ///
/// If `port` is not specified, `0` is used as the default. /// If `port` is not specified, `0` is used as the default.
pub extern "Lua" fn socketaddr(&self, addr: any, port: any) -> Result<lb_socketaddr> { pub extern "Lua" fn socketaddr(&self, s: any, port: any) -> Result<lb_socketaddr> {
if port != () { if port != () {
self.__new_skaddr(self.ipaddr(addr), port) self.__new_skaddr(self.ipaddr(s), port)
} else { } else {
if __istype(__ct.lb_socketaddr, addr) { if __istype(__ct.lb_socketaddr, s) {
__new(__ct.lb_socketaddr, addr) // copy constructor __new(__ct.lb_socketaddr, s) // copy constructor
} else if __istype(__ct.lb_ipaddr, addr) { } else if __istype(__ct.lb_ipaddr, s) {
self.__new_skaddr(addr, 0) // default port 0 self.__new_skaddr(s, 0) // default port 0
} else { } else {
self.__parse_skaddr(addr) self.__parse_skaddr(s)
} }
} }
} }
@ -123,12 +123,8 @@ impl lb_netlib {
SocketAddr::new(ip.0, port).into() SocketAddr::new(ip.0, port).into()
} }
extern "Lua-C" fn __parse_skaddr(&self, addr: &str) -> Result<lb_socketaddr> { extern "Lua-C" fn __parse_skaddr(&self, s: &str) -> Result<lb_socketaddr> {
Ok(if let Ok(addr) = addr.parse() { Ok(s.parse()?)
SocketAddr::new(addr, 0).into() // default port 0
} else {
addr.parse::<SocketAddr>()?.into()
})
} }
/// Creates a new TCP socket configured for IPv4. /// Creates a new TCP socket configured for IPv4.
@ -313,13 +309,13 @@ impl lb_socketaddr {
/// Sets the IP part of this address. /// Sets the IP part of this address.
/// ///
/// This function accepts the same arguments as [`ipaddr`](lb_netlib::ipaddr). /// This function accepts the same arguments as [`ipaddr`](lb_netlib::ipaddr).
pub extern "Lua" fn set_ip(&mut self, addr: any) -> &mut Self { pub extern "Lua" fn set_ip(&mut self, s: any) -> &mut Self {
if __istype(__ct.lb_ipaddr, addr) { if __istype(__ct.lb_ipaddr, s) {
self.__set_ip(addr); self.__set_ip(s);
} else if __istype(__ct.lb_socketaddr, addr) { } else if __istype(__ct.lb_socketaddr, s) {
self.__set_ip(addr.ip()); self.__set_ip(s.ip());
} else { } else {
self.__set_ip_parse(addr); self.__set_ip_parse(s);
} }
self self
} }
@ -328,8 +324,8 @@ impl lb_socketaddr {
self.0.set_ip(ip.0); self.0.set_ip(ip.0);
} }
extern "Lua-C" fn __set_ip_parse(&mut self, addr: &str) -> Result<()> { extern "Lua-C" fn __set_ip_parse(&mut self, s: &str) -> Result<()> {
Ok(self.0.set_ip(addr.parse()?)) Ok(self.0.set_ip(s.parse()?))
} }
/// Returns the port part of this address. /// Returns the port part of this address.

View File

@ -1,17 +0,0 @@
local ok, fs = pcall(require, "lb:fs")
if not ok then return end
describe("temp files", function()
test("temp_dir cleans itself", function()
local path
do
local dir = fs:temp_dir()
path = dir:path()
assert(path and path ~= "")
fs:write(path .. "/test.txt", "test file")
assert(fs:read(path .. "/test.txt") == "test file")
end
collectgarbage()
assert(not pcall(fs.read, fs, path .. "/test.txt"))
end)
end)

View File

@ -1,17 +0,0 @@
local ok, net = pcall(require, "lb:net")
if not ok then return end
describe("tcp", function()
describe("socket", function()
test("bind", function()
local socket = net:bind_tcp("127.0.0.1")
-- binds to the correct port
assert(tostring(socket:local_addr():ip()) == "127.0.0.1")
assert(socket:local_addr():port() ~= 0)
-- should not be able to rebind socket
assert(not pcall(socket.bind, socket, net:socketaddr("127.0.0.1")))
end)
end)
end)

View File

@ -1,103 +0,0 @@
local ok, task = pcall(require, "lb:task")
if not ok then return end
describe("spawn", function()
test("callback receives args", function()
spawn(function(...)
assert(select("#", ...) == 0)
end):await()
spawn(function(...)
assert(select("#", ...) == 1)
assert((...) == nil)
end, nil):await()
spawn(function(...)
assert(select("#", ...) == 4)
local args = table.pack(...)
assert(args[1] == 1 and args[2] == 2 and args[3] == nil and args[4] == 3)
end, 1, 2, nil, 3):await()
end)
test("await returns callback results", function()
local res = table.pack(spawn(function()
-- no returns
end):await())
assert(res.n == 0)
local res = table.pack(spawn(function()
return nil
end):await())
assert(res.n == 1 and res[1] == nil)
local res = table.pack(spawn(function()
return 1, 2, nil, 3
end):await())
assert(res.n == 4 and res[1] == 1 and res[2] == 2 and res[3] == nil and res[4] == 3)
end)
test("callback args and results", function()
local res = table.pack(spawn(function(...)
assert(select("#", ...) == 5)
local args = table.pack(...)
assert(args[1] == 5 and args[2] == 4 and args[3] == nil and args[4] == 3, args[5] == nil)
return 1, 3, nil
end, 5, 4, nil, 3, nil):await())
assert(res.n == 3 and res[1] == 1 and res[2] == 3 and res[3] == nil)
end)
test("order is consistent", function()
-- all tasks spawned in one batch should be resumed in the spawn order
local tasks, nums = {}, {}
for i = 1, 10 do
table.insert(
tasks,
spawn(function()
table.insert(nums, i)
end)
)
end
for i = 10, 1, -1 do
tasks[i]:await()
end
assert(#nums == 10)
for i = 1, 10 do
assert(nums[i] == i)
end
end)
end)
describe("sleep", function()
test("sleep is asynchronous", function()
local value
spawn(function()
value = "value"
end)
assert(value == nil)
task:sleep(100) -- implicit await: if it's synchronous, value wouldn't change
assert(value == "value")
end)
end)
describe("task", function()
test("properly unrefs arg and ret table", function()
local registry = debug.getregistry()
local ref, t
local cb = function()
return "my ret"
end
do
local task = spawn(cb, "my arg")
ref = task.__ref
t = registry[ref]
assert(type(t) == "table")
assert(t[1] == cb)
assert(t[2] == "my arg")
task:await()
assert(registry[task.__ref] == t)
assert(t[1] == "my ret")
end
collectgarbage()
assert(registry[ref] ~= t) -- if task unref'ed it, it should be either nil or the next freelist number
end)
end)