Compare commits
No commits in common. "3a7f2366e463bfb93a7b30988c087b195d99f143" and "40829cdfc61696ca11b16c0d421556a1c04db7a7" have entirely different histories.
3a7f2366e4
...
40829cdfc6
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -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"
|
||||||
|
@ -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"]
|
||||||
|
|
||||||
|
@ -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 }
|
||||||
|
@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
Loading…
x
Reference in New Issue
Block a user