mirror of
https://github.com/mlua-rs/mlua
synced 2026-06-08 16:05:43 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 09af3e021a | |||
| 9e3d495f91 | |||
| cab2e5a48e | |||
| 25a4879cde | |||
| ed48b11e7f | |||
| 559f9e6c6b | |||
| 458b06796c |
@@ -14,7 +14,7 @@ jobs:
|
||||
|
||||
- name: Generate code coverage
|
||||
run: |
|
||||
cargo tarpaulin --verbose --features lua53,vendored,async,send,serialize,macros --out xml --exclude-files benches --exclude-files build --exclude-files mlua_derive --exclude-files src/ffi --exclude-files tests
|
||||
cargo tarpaulin --verbose --features lua54,vendored,async,send,serialize,macros --out xml --exclude-files benches --exclude-files build --exclude-files mlua_derive --exclude-files src/ffi --exclude-files tests
|
||||
|
||||
- name: Upload to codecov.io
|
||||
uses: codecov/codecov-action@v1
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
## v0.6.6
|
||||
|
||||
- Fixed calculating `LUA_REGISTRYINDEX` when cross-compiling for lua51/jit (#82)
|
||||
- Updated documentation & examples
|
||||
|
||||
## v0.6.5
|
||||
|
||||
- Fixed bug when polling async futures (#77)
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mlua"
|
||||
version = "0.6.5" # remember to update html_root_url and mlua_derive
|
||||
version = "0.6.6" # remember to update html_root_url and mlua_derive
|
||||
authors = ["Aleksandr Orlenko <zxteam@pm.me>", "kyren <catherine@chucklefish.org>"]
|
||||
edition = "2018"
|
||||
repository = "https://github.com/khvzak/mlua"
|
||||
@@ -84,7 +84,7 @@ required-features = ["async", "serialize", "macros"]
|
||||
|
||||
[[example]]
|
||||
name = "async_http_server"
|
||||
required-features = ["async", "send"]
|
||||
required-features = ["async", "macros"]
|
||||
|
||||
[[example]]
|
||||
name = "async_tcp_server"
|
||||
|
||||
+8
-6
@@ -143,16 +143,18 @@ fn generate_glue() -> Result<()> {
|
||||
(version.0 * 100) + version.1
|
||||
)?;
|
||||
|
||||
let max_stack = if pointer_bit_width >= 32 {
|
||||
1_000_000
|
||||
} else {
|
||||
15_000
|
||||
};
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
writeln!(
|
||||
glue,
|
||||
"pub const LUA_REGISTRYINDEX: c_int = -{} - 1000;",
|
||||
max_stack
|
||||
if pointer_bit_width >= 32 {
|
||||
1_000_000
|
||||
} else {
|
||||
15_000
|
||||
}
|
||||
)?;
|
||||
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
||||
writeln!(glue, "pub const LUA_REGISTRYINDEX: c_int = -10000;")?;
|
||||
|
||||
// These two are only defined in lua 5.1
|
||||
writeln!(glue, "pub const LUA_ENVIRONINDEX: c_int = -10001;")?;
|
||||
|
||||
@@ -1,26 +1,17 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use hyper::body::{Body as HyperBody, HttpBody as _};
|
||||
use hyper::Client as HyperClient;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use mlua::{chunk, ExternalResult, Lua, Result, UserData, UserDataMethods};
|
||||
use mlua::{chunk, AnyUserData, ExternalResult, Lua, Result, UserData, UserDataMethods};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct BodyReader(Arc<Mutex<HyperBody>>);
|
||||
|
||||
impl BodyReader {
|
||||
fn new(body: HyperBody) -> Self {
|
||||
BodyReader(Arc::new(Mutex::new(body)))
|
||||
}
|
||||
}
|
||||
struct BodyReader(HyperBody);
|
||||
|
||||
impl UserData for BodyReader {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_method("read", |lua, reader, ()| async move {
|
||||
let mut reader = reader.0.lock().await;
|
||||
if let Some(bytes) = reader.data().await {
|
||||
methods.add_async_function("read", |lua, reader: AnyUserData| async move {
|
||||
let mut reader = reader.borrow_mut::<Self>()?;
|
||||
if let Some(bytes) = reader.0.data().await {
|
||||
let bytes = bytes.to_lua_err()?;
|
||||
return Some(lua.create_string(&bytes)).transpose();
|
||||
}
|
||||
@@ -50,7 +41,7 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
lua_resp.set("headers", headers)?;
|
||||
lua_resp.set("body", BodyReader::new(resp.into_body()))?;
|
||||
lua_resp.set("body", BodyReader(resp.into_body()))?;
|
||||
|
||||
Ok(lua_resp)
|
||||
})?;
|
||||
@@ -58,7 +49,7 @@ async fn main() -> Result<()> {
|
||||
let f = lua
|
||||
.load(chunk! {
|
||||
local res = $fetch_url(...)
|
||||
print(res.status)
|
||||
print("status: "..res.status)
|
||||
for key, vals in pairs(res.headers) do
|
||||
for _, val in ipairs(vals) do
|
||||
print(key..": "..val)
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
use std::future::Future;
|
||||
use std::net::SocketAddr;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use hyper::server::conn::AddrStream;
|
||||
use hyper::service::{make_service_fn, service_fn};
|
||||
use hyper::service::Service;
|
||||
use hyper::{Body, Request, Response, Server};
|
||||
|
||||
use mlua::{Error, Function, Lua, Result, Table, UserData, UserDataMethods};
|
||||
use mlua::{
|
||||
chunk, Error as LuaError, Function, Lua, String as LuaString, Table, UserData, UserDataMethods,
|
||||
};
|
||||
|
||||
struct LuaRequest(SocketAddr, Request<Body>);
|
||||
|
||||
@@ -15,75 +21,106 @@ impl UserData for LuaRequest {
|
||||
}
|
||||
}
|
||||
|
||||
async fn run_server(handler: Function<'static>) -> Result<()> {
|
||||
let make_svc = make_service_fn(|socket: &AddrStream| {
|
||||
let remote_addr = socket.remote_addr();
|
||||
let handler = handler.clone();
|
||||
async move {
|
||||
Ok::<_, Error>(service_fn(move |req: Request<Body>| {
|
||||
let handler = handler.clone();
|
||||
async move {
|
||||
let lua_req = LuaRequest(remote_addr, req);
|
||||
let lua_resp: Table = handler.call_async(lua_req).await?;
|
||||
let body = lua_resp
|
||||
.get::<_, Option<String>>("body")?
|
||||
.unwrap_or_default();
|
||||
pub struct Svc(Rc<Lua>, SocketAddr);
|
||||
|
||||
let mut resp = Response::builder()
|
||||
.status(lua_resp.get::<_, Option<u16>>("status")?.unwrap_or(200));
|
||||
impl Service<Request<Body>> for Svc {
|
||||
type Response = Response<Body>;
|
||||
type Error = LuaError;
|
||||
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
|
||||
|
||||
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn call(&mut self, req: Request<Body>) -> Self::Future {
|
||||
// If handler returns an error then generate 5xx response
|
||||
let lua = self.0.clone();
|
||||
let lua_req = LuaRequest(self.1, req);
|
||||
Box::pin(async move {
|
||||
let handler: Function = lua.named_registry_value("http_handler")?;
|
||||
match handler.call_async::<_, Table>(lua_req).await {
|
||||
Ok(lua_resp) => {
|
||||
let status = lua_resp.get::<_, Option<u16>>("status")?.unwrap_or(200);
|
||||
let mut resp = Response::builder().status(status);
|
||||
|
||||
// Set headers
|
||||
if let Some(headers) = lua_resp.get::<_, Option<Table>>("headers")? {
|
||||
for pair in headers.pairs::<String, String>() {
|
||||
for pair in headers.pairs::<String, LuaString>() {
|
||||
let (h, v) = pair?;
|
||||
resp = resp.header(&h, v);
|
||||
resp = resp.header(&h, v.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
Ok::<_, Error>(resp.body(Body::from(body)).unwrap())
|
||||
let body = lua_resp
|
||||
.get::<_, Option<LuaString>>("body")?
|
||||
.map(|b| Body::from(b.as_bytes().to_vec()))
|
||||
.unwrap_or_else(Body::empty);
|
||||
|
||||
Ok(resp.body(body).unwrap())
|
||||
}
|
||||
}))
|
||||
}
|
||||
});
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
Ok(Response::builder()
|
||||
.status(500)
|
||||
.body(Body::from("Internal Server Error"))
|
||||
.unwrap())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() {
|
||||
let lua = Rc::new(Lua::new());
|
||||
|
||||
// Create Lua handler function
|
||||
let handler: Function = lua
|
||||
.load(chunk! {
|
||||
function(req)
|
||||
return {
|
||||
status = 200,
|
||||
headers = {
|
||||
["X-Req-Method"] = req:method(),
|
||||
["X-Remote-Addr"] = req:remote_addr(),
|
||||
},
|
||||
body = "Hello from Lua!\n"
|
||||
}
|
||||
end
|
||||
})
|
||||
.eval()
|
||||
.expect("cannot create Lua handler");
|
||||
|
||||
// Store it in the Registry
|
||||
lua.set_named_registry_value("http_handler", handler)
|
||||
.expect("cannot store Lua handler");
|
||||
|
||||
let addr = ([127, 0, 0, 1], 3000).into();
|
||||
let server = Server::bind(&addr).executor(LocalExec).serve(make_svc);
|
||||
let server = Server::bind(&addr).executor(LocalExec).serve(MakeSvc(lua));
|
||||
|
||||
println!("Listening on http://{}", addr);
|
||||
|
||||
tokio::task::LocalSet::new()
|
||||
.run_until(server)
|
||||
.await
|
||||
.map_err(Error::external)
|
||||
// Create `LocalSet` to spawn !Send futures
|
||||
let local = tokio::task::LocalSet::new();
|
||||
local.run_until(server).await.expect("cannot run server")
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let lua = Lua::new().into_static();
|
||||
struct MakeSvc(Rc<Lua>);
|
||||
|
||||
let handler: Function = lua
|
||||
.load(
|
||||
r#"
|
||||
function(req)
|
||||
return {
|
||||
status = 200,
|
||||
headers = {
|
||||
["X-Req-Method"] = req:method(),
|
||||
["X-Remote-Addr"] = req:remote_addr(),
|
||||
},
|
||||
body = "Hello, World!\n"
|
||||
}
|
||||
end
|
||||
"#,
|
||||
)
|
||||
.eval()?;
|
||||
impl Service<&AddrStream> for MakeSvc {
|
||||
type Response = Svc;
|
||||
type Error = hyper::Error;
|
||||
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
|
||||
|
||||
run_server(handler).await?;
|
||||
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
// Consume the static reference and drop it.
|
||||
// This is safe as long as we don't hold any other references to Lua
|
||||
// or alive resources.
|
||||
unsafe { Lua::from_static(lua) };
|
||||
Ok(())
|
||||
fn call(&mut self, stream: &AddrStream) -> Self::Future {
|
||||
let lua = self.0.clone();
|
||||
let remote_addr = stream.remote_addr();
|
||||
Box::pin(async move { Ok(Svc(lua, remote_addr)) })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
||||
@@ -1,122 +1,121 @@
|
||||
use std::sync::Arc;
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
use std::rc::Rc;
|
||||
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::task;
|
||||
|
||||
use mlua::{chunk, Function, Lua, Result, String as LuaString, UserData, UserDataMethods};
|
||||
use mlua::{
|
||||
chunk, AnyUserData, Function, Lua, RegistryKey, String as LuaString, UserData, UserDataMethods,
|
||||
};
|
||||
|
||||
struct LuaTcp;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct LuaTcpListener(Arc<Mutex<TcpListener>>);
|
||||
|
||||
#[derive(Clone)]
|
||||
struct LuaTcpStream(Arc<Mutex<TcpStream>>);
|
||||
|
||||
impl UserData for LuaTcp {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_function("bind", |_, addr: String| async move {
|
||||
let listener = TcpListener::bind(addr).await?;
|
||||
Ok(LuaTcpListener(Arc::new(Mutex::new(listener))))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for LuaTcpListener {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_method("accept", |_, listener, ()| async move {
|
||||
let (stream, _) = listener.0.lock().await.accept().await?;
|
||||
Ok(LuaTcpStream(Arc::new(Mutex::new(stream))))
|
||||
});
|
||||
}
|
||||
}
|
||||
struct LuaTcpStream(TcpStream);
|
||||
|
||||
impl UserData for LuaTcpStream {
|
||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_async_method("peer_addr", |_, stream, ()| async move {
|
||||
Ok(stream.0.lock().await.peer_addr()?.to_string())
|
||||
methods.add_method("peer_addr", |_, this, ()| {
|
||||
Ok(this.0.peer_addr()?.to_string())
|
||||
});
|
||||
|
||||
methods.add_async_method("read", |lua, stream, size: usize| async move {
|
||||
let mut buf = vec![0; size];
|
||||
let n = stream.0.lock().await.read(&mut buf).await?;
|
||||
buf.truncate(n);
|
||||
lua.create_string(&buf)
|
||||
});
|
||||
methods.add_async_function(
|
||||
"read",
|
||||
|lua, (this, size): (AnyUserData, usize)| async move {
|
||||
let mut this = this.borrow_mut::<Self>()?;
|
||||
let mut buf = vec![0; size];
|
||||
let n = this.0.read(&mut buf).await?;
|
||||
buf.truncate(n);
|
||||
lua.create_string(&buf)
|
||||
},
|
||||
);
|
||||
|
||||
methods.add_async_method("write", |_, stream, data: LuaString| async move {
|
||||
let n = stream.0.lock().await.write(&data.as_bytes()).await?;
|
||||
Ok(n)
|
||||
});
|
||||
methods.add_async_function(
|
||||
"write",
|
||||
|_, (this, data): (AnyUserData, LuaString)| async move {
|
||||
let mut this = this.borrow_mut::<Self>()?;
|
||||
let n = this.0.write(&data.as_bytes()).await?;
|
||||
Ok(n)
|
||||
},
|
||||
);
|
||||
|
||||
methods.add_async_method("close", |_, stream, ()| async move {
|
||||
stream.0.lock().await.shutdown().await?;
|
||||
methods.add_async_function("close", |_, this: AnyUserData| async move {
|
||||
let mut this = this.borrow_mut::<Self>()?;
|
||||
this.0.shutdown().await?;
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async fn run_server(lua: &'static Lua) -> Result<()> {
|
||||
let spawn = lua.create_function(move |_, func: Function| {
|
||||
task::spawn_local(async move { func.call_async::<_, ()>(()).await });
|
||||
Ok(())
|
||||
})?;
|
||||
async fn run_server(lua: Lua, handler: RegistryKey) -> io::Result<()> {
|
||||
let addr: SocketAddr = ([127, 0, 0, 1], 3000).into();
|
||||
let listener = TcpListener::bind(addr).await.expect("cannot bind addr");
|
||||
|
||||
let tcp = LuaTcp;
|
||||
println!("Listening on {}", addr);
|
||||
|
||||
let server = lua
|
||||
let lua = Rc::new(lua);
|
||||
let handler = Rc::new(handler);
|
||||
loop {
|
||||
let (stream, _) = match listener.accept().await {
|
||||
Ok(res) => res,
|
||||
Err(err) if is_transient_error(&err) => continue,
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
|
||||
let lua = lua.clone();
|
||||
let handler = handler.clone();
|
||||
task::spawn_local(async move {
|
||||
let handler: Function = lua
|
||||
.registry_value(&handler)
|
||||
.expect("cannot get Lua handler");
|
||||
|
||||
let stream = LuaTcpStream(stream);
|
||||
if let Err(err) = handler.call_async::<_, ()>(stream).await {
|
||||
eprintln!("{}", err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() {
|
||||
let lua = Lua::new();
|
||||
|
||||
// Create Lua handler function
|
||||
let handler_fn = lua
|
||||
.load(chunk! {
|
||||
local addr = ...
|
||||
local listener = $tcp.bind(addr)
|
||||
print("listening on "..addr)
|
||||
|
||||
local accept_new = true
|
||||
while true do
|
||||
local stream = listener:accept()
|
||||
function(stream)
|
||||
local peer_addr = stream:peer_addr()
|
||||
print("connected from "..peer_addr)
|
||||
|
||||
if not accept_new then
|
||||
return
|
||||
end
|
||||
|
||||
$spawn(function()
|
||||
while true do
|
||||
local data = stream:read(100)
|
||||
data = data:match("^%s*(.-)%s*$") -- trim
|
||||
print("["..peer_addr.."] "..data)
|
||||
if data == "bye" then
|
||||
stream:write("bye bye\n")
|
||||
stream:close()
|
||||
return
|
||||
end
|
||||
if data == "exit" then
|
||||
stream:close()
|
||||
accept_new = false
|
||||
return
|
||||
end
|
||||
stream:write("echo: "..data.."\n")
|
||||
while true do
|
||||
local data = stream:read(100)
|
||||
data = data:match("^%s*(.-)%s*$") // trim
|
||||
print("["..peer_addr.."] "..data)
|
||||
if data == "bye" then
|
||||
stream:write("bye bye\n")
|
||||
stream:close()
|
||||
return
|
||||
end
|
||||
end)
|
||||
stream:write("echo: "..data.."\n")
|
||||
end
|
||||
end
|
||||
})
|
||||
.into_function()?;
|
||||
.eval::<Function>()
|
||||
.expect("cannot create Lua handler");
|
||||
|
||||
// Store it in the Registry
|
||||
let handler = lua
|
||||
.create_registry_value(handler_fn)
|
||||
.expect("cannot store Lua handler");
|
||||
|
||||
task::LocalSet::new()
|
||||
.run_until(server.call_async::<_, ()>("0.0.0.0:1234"))
|
||||
.run_until(run_server(lua, handler))
|
||||
.await
|
||||
.expect("cannot run server")
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let lua = Lua::new().into_static();
|
||||
|
||||
run_server(lua).await.unwrap();
|
||||
|
||||
// Consume the static reference and drop it.
|
||||
// This is safe as long as we don't hold any other references to Lua
|
||||
// or alive resources.
|
||||
unsafe { Lua::from_static(lua) };
|
||||
fn is_transient_error(e: &io::Error) -> bool {
|
||||
e.kind() == io::ErrorKind::ConnectionRefused
|
||||
|| e.kind() == io::ErrorKind::ConnectionAborted
|
||||
|| e.kind() == io::ErrorKind::ConnectionReset
|
||||
}
|
||||
|
||||
@@ -3,3 +3,9 @@ rustflags = [
|
||||
"-C", "link-arg=-undefined",
|
||||
"-C", "link-arg=dynamic_lookup",
|
||||
]
|
||||
|
||||
[target.aarch64-apple-darwin]
|
||||
rustflags = [
|
||||
"-C", "link-arg=-undefined",
|
||||
"-C", "link-arg=dynamic_lookup",
|
||||
]
|
||||
|
||||
+14
-12
@@ -96,8 +96,8 @@ pub enum Error {
|
||||
/// [`Thread::status`] can be used to check if the coroutine can be resumed without causing this
|
||||
/// error.
|
||||
///
|
||||
/// [`Thread::resume`]: struct.Thread.html#method.resume
|
||||
/// [`Thread::status`]: struct.Thread.html#method.status
|
||||
/// [`Thread::resume`]: crate::Thread::resume
|
||||
/// [`Thread::status`]: crate::Thread::status
|
||||
CoroutineInactive,
|
||||
/// An [`AnyUserData`] is not the expected type in a borrow.
|
||||
///
|
||||
@@ -105,15 +105,15 @@ pub enum Error {
|
||||
/// metamethods for binary operators. Refer to the documentation of [`UserDataMethods`] for
|
||||
/// details.
|
||||
///
|
||||
/// [`AnyUserData`]: struct.AnyUserData.html
|
||||
/// [`UserDataMethods`]: trait.UserDataMethods.html
|
||||
/// [`AnyUserData`]: crate::AnyUserData
|
||||
/// [`UserDataMethods`]: crate::UserDataMethods
|
||||
UserDataTypeMismatch,
|
||||
/// An [`AnyUserData`] borrow failed because it has been destructed.
|
||||
///
|
||||
/// This error can happen either due to to being destructed in a previous __gc, or due to being
|
||||
/// destructed from exiting a `Lua::scope` call.
|
||||
///
|
||||
/// [`AnyUserData`]: struct.AnyUserData.html
|
||||
/// [`AnyUserData`]: crate::AnyUserData
|
||||
UserDataDestructed,
|
||||
/// An [`AnyUserData`] immutable borrow failed because it is already borrowed mutably.
|
||||
///
|
||||
@@ -121,8 +121,8 @@ pub enum Error {
|
||||
/// tries to call a method on the same [`UserData`] type. Consider restructuring your API to
|
||||
/// prevent these errors.
|
||||
///
|
||||
/// [`AnyUserData`]: struct.AnyUserData.html
|
||||
/// [`UserData`]: trait.UserData.html
|
||||
/// [`AnyUserData`]: crate::AnyUserData
|
||||
/// [`UserData`]: crate::UserData
|
||||
UserDataBorrowError,
|
||||
/// An [`AnyUserData`] mutable borrow failed because it is already borrowed.
|
||||
///
|
||||
@@ -130,22 +130,24 @@ pub enum Error {
|
||||
/// tries to call a method on the same [`UserData`] type. Consider restructuring your API to
|
||||
/// prevent these errors.
|
||||
///
|
||||
/// [`AnyUserData`]: struct.AnyUserData.html
|
||||
/// [`UserData`]: trait.UserData.html
|
||||
/// [`AnyUserData`]: crate::AnyUserData
|
||||
/// [`UserData`]: crate::UserData
|
||||
UserDataBorrowMutError,
|
||||
/// A [`MetaMethod`] operation is restricted (typically for `__gc` or `__metatable`).
|
||||
///
|
||||
/// [`MetaMethod`]: enum.MetaMethod.html
|
||||
/// [`MetaMethod`]: crate::MetaMethod
|
||||
MetaMethodRestricted(StdString),
|
||||
/// A [`MetaMethod`] (eg. `__index` or `__newindex`) has invalid type.
|
||||
///
|
||||
/// [`MetaMethod`]: enum.MetaMethod.html
|
||||
/// [`MetaMethod`]: crate::MetaMethod
|
||||
MetaMethodTypeError {
|
||||
method: StdString,
|
||||
type_name: &'static str,
|
||||
message: Option<StdString>,
|
||||
},
|
||||
/// A `RegistryKey` produced from a different Lua state was used.
|
||||
/// A [`RegistryKey`] produced from a different Lua state was used.
|
||||
///
|
||||
/// [`RegistryKey`]: crate::RegistryKey
|
||||
MismatchedRegistryKey,
|
||||
/// A Rust callback returned `Err`, raising the contained `Error` as a Lua error.
|
||||
CallbackError {
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ impl<'lua> Function<'lua> {
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`AsyncThread`]: struct.AsyncThread.html
|
||||
/// [`AsyncThread`]: crate::AsyncThread
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
pub fn call_async<'fut, A, R>(&self, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ use crate::util::callback_error;
|
||||
/// found in the [Lua 5.3 documentation][lua_doc].
|
||||
///
|
||||
/// [lua_doc]: https://www.lua.org/manual/5.3/manual.html#lua_Debug
|
||||
/// [`Lua::set_hook`]: struct.Lua.html#method.set_hook
|
||||
/// [`Lua::set_hook`]: crate::Lua::set_hook
|
||||
#[derive(Clone)]
|
||||
pub struct Debug<'a> {
|
||||
ar: *mut lua_Debug,
|
||||
|
||||
+24
-24
@@ -50,29 +50,29 @@
|
||||
//! to [`Function`]s and [`UserData`].
|
||||
//!
|
||||
//! [Lua programming language]: https://www.lua.org/
|
||||
//! [`Lua`]: struct.Lua.html
|
||||
//! [executing]: struct.Chunk.html#method.exec
|
||||
//! [evaluating]: struct.Chunk.html#method.eval
|
||||
//! [globals]: struct.Lua.html#method.globals
|
||||
//! [`ToLua`]: trait.ToLua.html
|
||||
//! [`FromLua`]: trait.FromLua.html
|
||||
//! [`ToLuaMulti`]: trait.ToLuaMulti.html
|
||||
//! [`FromLuaMulti`]: trait.FromLuaMulti.html
|
||||
//! [`Function`]: struct.Function.html
|
||||
//! [`UserData`]: trait.UserData.html
|
||||
//! [`UserDataFields`]: trait.UserDataFields.html
|
||||
//! [`UserDataMethods`]: trait.UserDataMethods.html
|
||||
//! [`LuaSerdeExt`]: serde/trait.LuaSerdeExt.html
|
||||
//! [`Value`]: enum.Value.html
|
||||
//! [`create_async_function`]: struct.Lua.html#method.create_async_function
|
||||
//! [`call_async`]: struct.Function.html#method.call_async
|
||||
//! [`AsyncThread`]: struct.AsyncThread.html
|
||||
//! [`Future`]: ../futures_core/future/trait.Future.html
|
||||
//! [`Lua`]: crate::Lua
|
||||
//! [executing]: crate::Chunk::exec
|
||||
//! [evaluating]: crate::Chunk::eval
|
||||
//! [globals]: crate::Lua::globals
|
||||
//! [`ToLua`]: crate::ToLua
|
||||
//! [`FromLua`]: crate::FromLua
|
||||
//! [`ToLuaMulti`]: crate::ToLuaMulti
|
||||
//! [`FromLuaMulti`]: crate::FromLuaMulti
|
||||
//! [`Function`]: crate::Function
|
||||
//! [`UserData`]: crate::UserData
|
||||
//! [`UserDataFields`]: crate::UserDataFields
|
||||
//! [`UserDataMethods`]: crate::UserDataMethods
|
||||
//! [`LuaSerdeExt`]: crate::LuaSerdeExt
|
||||
//! [`Value`]: crate::Value
|
||||
//! [`create_async_function`]: crate::Lua::create_async_function
|
||||
//! [`call_async`]: crate::Function::call_async
|
||||
//! [`AsyncThread`]: crate::AsyncThread
|
||||
//! [`Future`]: std::future::Future
|
||||
//! [`serde::Serialize`]: https://docs.serde.rs/serde/ser/trait.Serialize.html
|
||||
//! [`serde::Deserialize`]: https://docs.serde.rs/serde/de/trait.Deserialize.html
|
||||
|
||||
// mlua types in rustdoc of other crates get linked to here.
|
||||
#![doc(html_root_url = "https://docs.rs/mlua/0.6.5")]
|
||||
#![doc(html_root_url = "https://docs.rs/mlua/0.6.6")]
|
||||
// Deny warnings inside doc tests / examples. When this isn't present, rustdoc doesn't show *any*
|
||||
// warnings at all.
|
||||
#![doc(test(attr(deny(warnings))))]
|
||||
@@ -98,6 +98,8 @@ mod userdata;
|
||||
mod util;
|
||||
mod value;
|
||||
|
||||
pub mod prelude;
|
||||
|
||||
pub use crate::{ffi::lua_CFunction, ffi::lua_State};
|
||||
|
||||
pub use crate::error::{Error, ExternalError, ExternalResult, Result};
|
||||
@@ -120,13 +122,11 @@ pub use crate::value::{FromLua, FromLuaMulti, MultiValue, Nil, ToLua, ToLuaMulti
|
||||
pub use crate::thread::AsyncThread;
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "serialize")))]
|
||||
#[doc(inline)]
|
||||
pub use crate::serde::{
|
||||
de::Options as DeserializeOptions, ser::Options as SerializeOptions, LuaSerdeExt,
|
||||
};
|
||||
|
||||
pub mod prelude;
|
||||
#[cfg(feature = "serialize")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "serialize")))]
|
||||
pub mod serde;
|
||||
@@ -185,9 +185,9 @@ extern crate mlua_derive;
|
||||
///
|
||||
/// Everything else should work.
|
||||
///
|
||||
/// [`AsChunk`]: trait.AsChunk.html
|
||||
/// [`UserData`]: trait.UserData.html
|
||||
/// [`ToLua`]: trait.ToLua.html
|
||||
/// [`AsChunk`]: crate::AsChunk
|
||||
/// [`UserData`]: crate::UserData
|
||||
/// [`ToLua`]: crate::ToLua
|
||||
#[cfg(any(feature = "macros"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
|
||||
pub use mlua_derive::chunk;
|
||||
|
||||
+24
-23
@@ -210,7 +210,7 @@ impl Lua {
|
||||
///
|
||||
/// See [`StdLib`] documentation for a list of unsafe modules that cannot be loaded.
|
||||
///
|
||||
/// [`StdLib`]: struct.StdLib.html
|
||||
/// [`StdLib`]: crate::StdLib
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> Lua {
|
||||
mlua_expect!(
|
||||
@@ -237,7 +237,7 @@ impl Lua {
|
||||
///
|
||||
/// See [`StdLib`] documentation for a list of unsafe modules that cannot be loaded.
|
||||
///
|
||||
/// [`StdLib`]: struct.StdLib.html
|
||||
/// [`StdLib`]: crate::StdLib
|
||||
pub fn new_with(libs: StdLib, options: LuaOptions) -> Result<Lua> {
|
||||
if libs.contains(StdLib::DEBUG) {
|
||||
return Err(Error::SafetyError(
|
||||
@@ -271,7 +271,7 @@ impl Lua {
|
||||
/// # Safety
|
||||
/// The created Lua state will not have safety guarantees and allow to load C modules.
|
||||
///
|
||||
/// [`StdLib`]: struct.StdLib.html
|
||||
/// [`StdLib`]: crate::StdLib
|
||||
pub unsafe fn unsafe_new_with(libs: StdLib, options: LuaOptions) -> Lua {
|
||||
ffi::keep_lua_symbols();
|
||||
Self::inner_new(libs, options)
|
||||
@@ -513,7 +513,7 @@ impl Lua {
|
||||
///
|
||||
/// Use the [`StdLib`] flags to specify the libraries you want to load.
|
||||
///
|
||||
/// [`StdLib`]: struct.StdLib.html
|
||||
/// [`StdLib`]: crate::StdLib
|
||||
pub fn load_from_std_lib(&self, libs: StdLib) -> Result<()> {
|
||||
if self.safe && libs.contains(StdLib::DEBUG) {
|
||||
return Err(Error::SafetyError(
|
||||
@@ -700,8 +700,8 @@ impl Lua {
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`HookTriggers`]: struct.HookTriggers.html
|
||||
/// [`HookTriggers.every_nth_instruction`]: struct.HookTriggers.html#field.every_nth_instruction
|
||||
/// [`HookTriggers`]: crate::HookTriggers
|
||||
/// [`HookTriggers.every_nth_instruction`]: crate::HookTriggers::every_nth_instruction
|
||||
pub fn set_hook<F>(&self, triggers: HookTriggers, callback: F) -> Result<()>
|
||||
where
|
||||
F: 'static + MaybeSend + FnMut(&Lua, Debug) -> Result<()>,
|
||||
@@ -906,10 +906,11 @@ impl Lua {
|
||||
/// similar on the returned builder. Code is not even parsed until one of these methods is
|
||||
/// called.
|
||||
///
|
||||
/// If this `Lua` was created with `unsafe_new`, `load` will automatically detect and load
|
||||
/// If this `Lua` was created with [`unsafe_new`], `load` will automatically detect and load
|
||||
/// chunks of either text or binary type, as if passing `bt` mode to `luaL_loadbufferx`.
|
||||
///
|
||||
/// [`Chunk::exec`]: struct.Chunk.html#method.exec
|
||||
/// [`Chunk::exec`]: crate::Chunk::exec
|
||||
/// [`unsafe_new`]: #method.unsafe_new
|
||||
#[track_caller]
|
||||
pub fn load<'lua, 'a, S>(&'lua self, source: &'a S) -> Chunk<'lua, 'a>
|
||||
where
|
||||
@@ -1105,8 +1106,8 @@ impl Lua {
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`ToLua`]: trait.ToLua.html
|
||||
/// [`ToLuaMulti`]: trait.ToLuaMulti.html
|
||||
/// [`ToLua`]: crate::ToLua
|
||||
/// [`ToLuaMulti`]: crate::ToLuaMulti
|
||||
pub fn create_function<'lua, 'callback, A, R, F>(&'lua self, func: F) -> Result<Function<'lua>>
|
||||
where
|
||||
'lua: 'callback,
|
||||
@@ -1191,8 +1192,8 @@ impl Lua {
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`Thread`]: struct.Thread.html
|
||||
/// [`AsyncThread`]: struct.AsyncThread.html
|
||||
/// [`Thread`]: crate::Thread
|
||||
/// [`AsyncThread`]: crate::AsyncThread
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
pub fn create_async_function<'lua, 'callback, A, R, F, FR>(
|
||||
@@ -1484,7 +1485,7 @@ impl Lua {
|
||||
/// Be warned, garbage collection of values held inside the registry is not automatic, see
|
||||
/// [`RegistryKey`] for more details.
|
||||
///
|
||||
/// [`RegistryKey`]: struct.RegistryKey.html
|
||||
/// [`RegistryKey`]: crate::RegistryKey
|
||||
pub fn create_registry_value<'lua, T: ToLua<'lua>>(&'lua self, t: T) -> Result<RegistryKey> {
|
||||
let t = t.to_lua(self)?;
|
||||
unsafe {
|
||||
@@ -2206,7 +2207,7 @@ impl Lua {
|
||||
|
||||
/// Returned from [`Lua::load`] and is used to finalize loading and executing Lua main chunks.
|
||||
///
|
||||
/// [`Lua::load`]: struct.Lua.html#method.load
|
||||
/// [`Lua::load`]: crate::Lua::load
|
||||
#[must_use = "`Chunk`s do nothing unless one of `exec`, `eval`, `call`, or `into_function` are called on them"]
|
||||
pub struct Chunk<'lua, 'a> {
|
||||
lua: &'lua Lua,
|
||||
@@ -2226,7 +2227,7 @@ pub enum ChunkMode {
|
||||
/// Trait for types [loadable by Lua] and convertible to a [`Chunk`]
|
||||
///
|
||||
/// [loadable by Lua]: https://www.lua.org/manual/5.3/manual.html#3.3.2
|
||||
/// [`Chunk`]: struct.Chunk.html
|
||||
/// [`Chunk`]: crate::Chunk
|
||||
pub trait AsChunk<'lua> {
|
||||
/// Returns chunk data (can be text or binary)
|
||||
fn source(&self) -> &[u8];
|
||||
@@ -2284,7 +2285,7 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
|
||||
/// Lua does not check the consistency of binary chunks, therefore this mode is allowed only
|
||||
/// for instances created with [`Lua::unsafe_new`].
|
||||
///
|
||||
/// [`Lua::unsafe_new`]: struct.Lua.html#method.unsafe_new
|
||||
/// [`Lua::unsafe_new`]: crate::Lua::unsafe_new
|
||||
pub fn set_mode(mut self, mode: ChunkMode) -> Chunk<'lua, 'a> {
|
||||
self.mode = Some(mode);
|
||||
self
|
||||
@@ -2300,11 +2301,11 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
|
||||
|
||||
/// Asynchronously execute this chunk of code.
|
||||
///
|
||||
/// See [`Chunk::exec`] for more details.
|
||||
/// See [`exec`] for more details.
|
||||
///
|
||||
/// Requires `feature = "async"`
|
||||
///
|
||||
/// [`Chunk::exec`]: struct.Chunk.html#method.exec
|
||||
/// [`exec`]: #method.exec
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
pub fn exec_async<'fut>(self) -> LocalBoxFuture<'fut, Result<()>>
|
||||
@@ -2340,11 +2341,11 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
|
||||
|
||||
/// Asynchronously evaluate the chunk as either an expression or block.
|
||||
///
|
||||
/// See [`Chunk::eval`] for more details.
|
||||
/// See [`eval`] for more details.
|
||||
///
|
||||
/// Requires `feature = "async"`
|
||||
///
|
||||
/// [`Chunk::eval`]: struct.Chunk.html#method.eval
|
||||
/// [`eval`]: #method.eval
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
pub fn eval_async<'fut, R>(self) -> LocalBoxFuture<'fut, Result<R>>
|
||||
@@ -2378,11 +2379,11 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
|
||||
|
||||
/// Load the chunk function and asynchronously call it with the given arguments.
|
||||
///
|
||||
/// See [`Chunk::call`] for more details.
|
||||
/// See [`call`] for more details.
|
||||
///
|
||||
/// Requires `feature = "async"`
|
||||
///
|
||||
/// [`Chunk::call`]: struct.Chunk.html#method.call
|
||||
/// [`call`]: #method.call
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
pub fn call_async<'fut, A, R>(self, args: A) -> LocalBoxFuture<'fut, Result<R>>
|
||||
@@ -3117,7 +3118,7 @@ impl<'lua, T: 'static + UserData> UserDataFields<'lua, T> for StaticUserDataFiel
|
||||
{
|
||||
self.field_getters.push((
|
||||
name.as_ref().to_vec(),
|
||||
StaticUserDataMethods::<T>::box_function(move |lua, data| function(lua, data)),
|
||||
StaticUserDataMethods::<T>::box_function(function),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -76,8 +76,8 @@ impl<'lua> FromLuaMulti<'lua> for MultiValue<'lua> {
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`FromLua`]: trait.FromLua.html
|
||||
/// [`MultiValue`]: struct.MultiValue.html
|
||||
/// [`FromLua`]: crate::FromLua
|
||||
/// [`MultiValue`]: crate::MultiValue
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Variadic<T>(Vec<T>);
|
||||
|
||||
|
||||
+3
-1
@@ -1,5 +1,6 @@
|
||||
//! Re-exports most types with an extra `Lua*` prefix to prevent name clashes.
|
||||
|
||||
#[doc(no_inline)]
|
||||
pub use crate::{
|
||||
AnyUserData as LuaAnyUserData, Chunk as LuaChunk, Error as LuaError,
|
||||
ExternalError as LuaExternalError, ExternalResult as LuaExternalResult, FromLua, FromLuaMulti,
|
||||
@@ -14,10 +15,11 @@ pub use crate::{
|
||||
};
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::AsyncThread as LuaAsyncThread;
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
#[doc(inline)]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::{
|
||||
DeserializeOptions as LuaDeserializeOptions, LuaSerdeExt,
|
||||
SerializeOptions as LuaSerializeOptions,
|
||||
|
||||
+15
-15
@@ -35,7 +35,7 @@ use {
|
||||
///
|
||||
/// See [`Lua::scope`] for more details.
|
||||
///
|
||||
/// [`Lua::scope`]: struct.Lua.html#method.scope
|
||||
/// [`Lua::scope`]: crate::Lua.html::scope
|
||||
pub struct Scope<'lua, 'scope> {
|
||||
lua: &'lua Lua,
|
||||
destructors: RefCell<Vec<(LuaRef<'lua>, DestructorCallback<'lua>)>>,
|
||||
@@ -58,8 +58,8 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
||||
/// This is a version of [`Lua::create_function`] that creates a callback which expires on
|
||||
/// scope drop. See [`Lua::scope`] for more details.
|
||||
///
|
||||
/// [`Lua::create_function`]: struct.Lua.html#method.create_function
|
||||
/// [`Lua::scope`]: struct.Lua.html#method.scope
|
||||
/// [`Lua::create_function`]: crate::Lua::create_function
|
||||
/// [`Lua::scope`]: crate::Lua::scope
|
||||
pub fn create_function<'callback, A, R, F>(&'callback self, func: F) -> Result<Function<'lua>>
|
||||
where
|
||||
A: FromLuaMulti<'callback>,
|
||||
@@ -87,8 +87,8 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
||||
/// This is a version of [`Lua::create_function_mut`] that creates a callback which expires
|
||||
/// on scope drop. See [`Lua::scope`] and [`Scope::create_function`] for more details.
|
||||
///
|
||||
/// [`Lua::create_function_mut`]: struct.Lua.html#method.create_function_mut
|
||||
/// [`Lua::scope`]: struct.Lua.html#method.scope
|
||||
/// [`Lua::create_function_mut`]: crate::Lua::create_function_mut
|
||||
/// [`Lua::scope`]: crate::Lua::scope
|
||||
/// [`Scope::create_function`]: #method.create_function
|
||||
pub fn create_function_mut<'callback, A, R, F>(
|
||||
&'callback self,
|
||||
@@ -114,9 +114,9 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
||||
///
|
||||
/// Requires `feature = "async"`
|
||||
///
|
||||
/// [`Lua::create_async_function`]: struct.Lua.html#method.create_async_function
|
||||
/// [`Lua::scope`]: struct.Lua.html#method.scope
|
||||
/// [`Lua::async_scope`]: struct.Lua.html#method.async_scope
|
||||
/// [`Lua::create_async_function`]: crate::Lua::create_async_function
|
||||
/// [`Lua::scope`]: crate::Lua::scope
|
||||
/// [`Lua::async_scope`]: crate::Lua::async_scope
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
pub fn create_async_function<'callback, A, R, F, FR>(
|
||||
@@ -147,8 +147,8 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
||||
/// UserData be 'static).
|
||||
/// See [`Lua::scope`] for more details.
|
||||
///
|
||||
/// [`Lua::create_userdata`]: struct.Lua.html#method.create_userdata
|
||||
/// [`Lua::scope`]: struct.Lua.html#method.scope
|
||||
/// [`Lua::create_userdata`]: crate::Lua::create_userdata
|
||||
/// [`Lua::scope`]: crate::Lua::scope
|
||||
pub fn create_userdata<T>(&self, data: T) -> Result<AnyUserData<'lua>>
|
||||
where
|
||||
T: 'static + UserData,
|
||||
@@ -165,8 +165,8 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
||||
///
|
||||
/// Requires `feature = "serialize"`
|
||||
///
|
||||
/// [`Lua::create_ser_userdata`]: struct.Lua.html#method.create_ser_userdata
|
||||
/// [`Lua::scope`]: struct.Lua.html#method.scope
|
||||
/// [`Lua::create_ser_userdata`]: crate::Lua::create_ser_userdata
|
||||
/// [`Lua::scope`]: crate::Lua::scope
|
||||
#[cfg(feature = "serialize")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "serialize")))]
|
||||
pub fn create_ser_userdata<T>(&self, data: T) -> Result<AnyUserData<'lua>>
|
||||
@@ -234,9 +234,9 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
||||
/// creating the userdata metatable each time a new userdata is created.
|
||||
///
|
||||
/// [`Scope::create_userdata`]: #method.create_userdata
|
||||
/// [`Lua::create_userdata`]: struct.Lua.html#method.create_userdata
|
||||
/// [`Lua::scope`]: struct.Lua.html#method.scope
|
||||
/// [`UserDataMethods`]: trait.UserDataMethods.html
|
||||
/// [`Lua::create_userdata`]: crate::Lua::create_userdata
|
||||
/// [`Lua::scope`]:crate::Lua::scope
|
||||
/// [`UserDataMethods`]: crate::UserDataMethods
|
||||
pub fn create_nonstatic_userdata<T>(&self, data: T) -> Result<AnyUserData<'lua>>
|
||||
where
|
||||
T: 'scope + UserData,
|
||||
|
||||
+7
-2
@@ -23,11 +23,16 @@ pub struct Deserializer<'lua> {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[non_exhaustive]
|
||||
pub struct Options {
|
||||
/// If true, an attempt to serialize types such as `Thread`, `UserData`, `LightUserData`
|
||||
/// and `Error` will cause an error.
|
||||
/// If true, an attempt to serialize types such as [`Thread`], [`UserData`], [`LightUserData`]
|
||||
/// and [`Error`] will cause an error.
|
||||
/// Otherwise these types skipped when iterating or serialized as unit type.
|
||||
///
|
||||
/// Default: **true**
|
||||
///
|
||||
/// [`Thread`]: crate::Thread
|
||||
/// [`UserData`]: crate::UserData
|
||||
/// [`LightUserData`]: crate::LightUserData
|
||||
/// [`Error`]: crate::Error
|
||||
pub deny_unsupported_types: bool,
|
||||
|
||||
/// If true, an attempt to serialize a recursive table (table that refers to itself)
|
||||
|
||||
+8
-8
@@ -69,11 +69,11 @@ pub trait LuaSerdeExt<'lua> {
|
||||
/// ```
|
||||
fn array_metatable(&'lua self) -> Table<'lua>;
|
||||
|
||||
/// Converts `T` into a `Value` instance.
|
||||
/// Converts `T` into a [`Value`] instance.
|
||||
///
|
||||
/// Requires `feature = "serialize"`
|
||||
///
|
||||
/// [`Value`]: enum.Value.html
|
||||
/// [`Value`]: crate::Value
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@@ -102,11 +102,11 @@ pub trait LuaSerdeExt<'lua> {
|
||||
/// ```
|
||||
fn to_value<T: Serialize + ?Sized>(&'lua self, t: &T) -> Result<Value<'lua>>;
|
||||
|
||||
/// Converts `T` into a `Value` instance with options.
|
||||
/// Converts `T` into a [`Value`] instance with options.
|
||||
///
|
||||
/// Requires `feature = "serialize"`
|
||||
///
|
||||
/// [`Value`]: enum.Value.html
|
||||
/// [`Value`]: crate::Value
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@@ -129,11 +129,11 @@ pub trait LuaSerdeExt<'lua> {
|
||||
where
|
||||
T: Serialize + ?Sized;
|
||||
|
||||
/// Deserializes a `Value` into any serde deserializable object.
|
||||
/// Deserializes a [`Value`] into any serde deserializable object.
|
||||
///
|
||||
/// Requires `feature = "serialize"`
|
||||
///
|
||||
/// [`Value`]: enum.Value.html
|
||||
/// [`Value`]: crate::Value
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@@ -159,11 +159,11 @@ pub trait LuaSerdeExt<'lua> {
|
||||
/// ```
|
||||
fn from_value<T: Deserialize<'lua>>(&'lua self, value: Value<'lua>) -> Result<T>;
|
||||
|
||||
/// Deserializes a `Value` into any serde deserializable object with options.
|
||||
/// Deserializes a [`Value`] into any serde deserializable object with options.
|
||||
///
|
||||
/// Requires `feature = "serialize"`
|
||||
///
|
||||
/// [`Value`]: enum.Value.html
|
||||
/// [`Value`]: crate::Value
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
||||
+7
-7
@@ -28,16 +28,16 @@ pub struct Options {
|
||||
///
|
||||
/// Default: **true**
|
||||
///
|
||||
/// [`array_metatable`]: ../trait.LuaSerdeExt.html#tymethod.array_metatable
|
||||
/// [`array_metatable`]: crate::LuaSerdeExt::array_metatable
|
||||
pub set_array_metatable: bool,
|
||||
|
||||
/// If true, serialize `None` (part of `Option` type) to [`null`].
|
||||
/// If true, serialize `None` (part of the `Option` type) to [`null`].
|
||||
/// Otherwise it will be set to Lua [`Nil`].
|
||||
///
|
||||
/// Default: **true**
|
||||
///
|
||||
/// [`null`]: ../trait.LuaSerdeExt.html#tymethod.null
|
||||
/// [`Nil`]: ../../enum.Value.html#variant.Nil
|
||||
/// [`null`]: crate::LuaSerdeExt::null
|
||||
/// [`Nil`]: crate::Value::Nil
|
||||
pub serialize_none_to_null: bool,
|
||||
|
||||
/// If true, serialize `Unit` (type of `()` in Rust) and Unit structs to [`null`].
|
||||
@@ -45,8 +45,8 @@ pub struct Options {
|
||||
///
|
||||
/// Default: **true**
|
||||
///
|
||||
/// [`null`]: ../trait.LuaSerdeExt.html#tymethod.null
|
||||
/// [`Nil`]: ../../enum.Value.html#variant.Nil
|
||||
/// [`null`]: crate::LuaSerdeExt::null
|
||||
/// [`Nil`]: crate::Value::Nil
|
||||
pub serialize_unit_to_null: bool,
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ impl Default for Options {
|
||||
}
|
||||
|
||||
impl Options {
|
||||
/// Returns a new instance of `Options` with default parameters.
|
||||
/// Returns a new instance of [`Options`] with default parameters.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
+4
-4
@@ -378,7 +378,7 @@ impl<'lua> Table<'lua> {
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`Result`]: type.Result.html
|
||||
/// [`Result`]: crate::Result
|
||||
/// [Lua manual]: http://www.lua.org/manual/5.3/manual.html#pdf-next
|
||||
pub fn pairs<K: FromLua<'lua>, V: FromLua<'lua>>(self) -> TablePairs<'lua, K, V> {
|
||||
TablePairs {
|
||||
@@ -427,7 +427,7 @@ impl<'lua> Table<'lua> {
|
||||
/// ```
|
||||
///
|
||||
/// [`pairs`]: #method.pairs
|
||||
/// [`Result`]: type.Result.html
|
||||
/// [`Result`]: crate::Result
|
||||
/// [Lua manual]: http://www.lua.org/manual/5.3/manual.html#pdf-next
|
||||
pub fn sequence_values<V: FromLua<'lua>>(self) -> TableSequence<'lua, V> {
|
||||
TableSequence {
|
||||
@@ -645,7 +645,7 @@ impl<'lua> Serialize for Table<'lua> {
|
||||
///
|
||||
/// This struct is created by the [`Table::pairs`] method.
|
||||
///
|
||||
/// [`Table::pairs`]: struct.Table.html#method.pairs
|
||||
/// [`Table::pairs`]: crate::Table::pairs
|
||||
pub struct TablePairs<'lua, K, V> {
|
||||
table: LuaRef<'lua>,
|
||||
key: Option<Value<'lua>>,
|
||||
@@ -704,7 +704,7 @@ where
|
||||
///
|
||||
/// This struct is created by the [`Table::sequence_values`] method.
|
||||
///
|
||||
/// [`Table::sequence_values`]: struct.Table.html#method.sequence_values
|
||||
/// [`Table::sequence_values`]: crate::Table::sequence_values
|
||||
pub struct TableSequence<'lua, V> {
|
||||
table: LuaRef<'lua>,
|
||||
index: Option<Integer>,
|
||||
|
||||
+9
-5
@@ -33,7 +33,7 @@ pub enum ThreadStatus {
|
||||
///
|
||||
/// If a thread is in this state, it can be resumed by calling [`Thread::resume`].
|
||||
///
|
||||
/// [`Thread::resume`]: struct.Thread.html#method.resume
|
||||
/// [`Thread::resume`]: crate::Thread::resume
|
||||
Resumable,
|
||||
/// Either the thread has finished executing, or the thread is currently running.
|
||||
Unresumable,
|
||||
@@ -49,8 +49,8 @@ pub struct Thread<'lua>(pub(crate) LuaRef<'lua>);
|
||||
///
|
||||
/// Requires `feature = "async"`
|
||||
///
|
||||
/// [`Future`]: ../futures_core/future/trait.Future.html
|
||||
/// [`Stream`]: ../futures_core/stream/trait.Stream.html
|
||||
/// [`Future`]: futures_core::future::Future
|
||||
/// [`Stream`]: futures_core::stream::Stream
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
#[derive(Debug)]
|
||||
@@ -203,10 +203,10 @@ impl<'lua> Thread<'lua> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts Thread to an AsyncThread which implements Future and Stream traits.
|
||||
/// Converts Thread to an AsyncThread which implements [`Future`] and [`Stream`] traits.
|
||||
///
|
||||
/// `args` are passed as arguments to the thread function for first call.
|
||||
/// The object call `resume()` while polling and also allows to run rust futures
|
||||
/// The object calls [`resume()`] while polling and also allows to run rust futures
|
||||
/// to completion using an executor.
|
||||
///
|
||||
/// Using AsyncThread as a Stream allows to iterate through `coroutine.yield()`
|
||||
@@ -215,6 +215,10 @@ impl<'lua> Thread<'lua> {
|
||||
///
|
||||
/// Requires `feature = "async"`
|
||||
///
|
||||
/// [`Future`]: futures_core::future::Future
|
||||
/// [`Stream`]: futures_core::stream::Stream
|
||||
/// [`resume()`]: https://www.lua.org/manual/5.4/manual.html#lua_resume
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
||||
+9
-7
@@ -71,15 +71,17 @@ pub(crate) struct DestructedUserdataMT;
|
||||
/// garbage collected on Drop, but it can be removed with [`Lua::remove_registry_value`],
|
||||
/// and instances not manually removed can be garbage collected with [`Lua::expire_registry_values`].
|
||||
///
|
||||
/// Be warned, If you place this into Lua via a `UserData` type or a rust callback, it is *very
|
||||
/// Be warned, If you place this into Lua via a [`UserData`] type or a rust callback, it is *very
|
||||
/// easy* to accidentally cause reference cycles that the Lua garbage collector cannot resolve.
|
||||
/// Instead of placing a `RegistryKey` into a `UserData` type, prefer instead to use
|
||||
/// [`UserData::set_user_value`] / [`UserData::get_user_value`].
|
||||
/// Instead of placing a [`RegistryKey`] into a [`UserData`] type, prefer instead to use
|
||||
/// [`AnyUserData::set_user_value`] / [`AnyUserData::get_user_value`].
|
||||
///
|
||||
/// [`Lua::remove_registry_value`]: struct.Lua.html#method.remove_registry_value
|
||||
/// [`Lua::expire_registry_values`]: struct.Lua.html#method.expire_registry_values
|
||||
/// [`UserData::set_user_value`]: struct.UserData.html#method.set_user_value
|
||||
/// [`UserData::get_user_value`]: struct.UserData.html#method.get_user_value
|
||||
/// [`UserData`]: crate::UserData
|
||||
/// [`RegistryKey`]: crate::RegistryKey
|
||||
/// [`Lua::remove_registry_value`]: crate::Lua::remove_registry_value
|
||||
/// [`Lua::expire_registry_values`]: crate::Lua::expire_registry_values
|
||||
/// [`AnyUserData::set_user_value`]: crate::AnyUserData::set_user_value
|
||||
/// [`AnyUserData::get_user_value`]: crate::AnyUserData::get_user_value
|
||||
pub struct RegistryKey {
|
||||
pub(crate) registry_id: c_int,
|
||||
pub(crate) unref_list: Arc<Mutex<Option<Vec<c_int>>>>,
|
||||
|
||||
+17
-17
@@ -34,7 +34,7 @@ use crate::types::AsyncCallback;
|
||||
/// Currently, this mechanism does not allow overriding the `__gc` metamethod, since there is
|
||||
/// generally no need to do so: [`UserData`] implementors can instead just implement `Drop`.
|
||||
///
|
||||
/// [`UserData`]: trait.UserData.html
|
||||
/// [`UserData`]: crate::UserData
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MetaMethod {
|
||||
/// The `+` operator.
|
||||
@@ -271,7 +271,7 @@ impl From<&str> for MetaMethod {
|
||||
|
||||
/// Method registry for [`UserData`] implementors.
|
||||
///
|
||||
/// [`UserData`]: trait.UserData.html
|
||||
/// [`UserData`]: crate::UserData
|
||||
pub trait UserDataMethods<'lua, T: UserData> {
|
||||
/// Add a regular method which accepts a `&T` as the first parameter.
|
||||
///
|
||||
@@ -325,7 +325,7 @@ pub trait UserDataMethods<'lua, T: UserData> {
|
||||
///
|
||||
/// Prefer to use [`add_method`] or [`add_method_mut`] as they are easier to use.
|
||||
///
|
||||
/// [`AnyUserData`]: struct.AnyUserData.html
|
||||
/// [`AnyUserData`]: crate::AnyUserData
|
||||
/// [`add_method`]: #method.add_method
|
||||
/// [`add_method_mut`]: #method.add_method_mut
|
||||
fn add_function<S, A, R, F>(&mut self, name: &S, function: F)
|
||||
@@ -436,7 +436,7 @@ pub trait UserDataMethods<'lua, T: UserData> {
|
||||
|
||||
/// Field registry for [`UserData`] implementors.
|
||||
///
|
||||
/// [`UserData`]: trait.UserData.html
|
||||
/// [`UserData`]: crate::UserData
|
||||
pub trait UserDataFields<'lua, T: UserData> {
|
||||
/// Add a regular field getter as a method which accepts a `&T` as the parameter.
|
||||
///
|
||||
@@ -469,7 +469,7 @@ pub trait UserDataFields<'lua, T: UserData> {
|
||||
///
|
||||
/// Prefer to use [`add_field_method_get`] as it is easier to use.
|
||||
///
|
||||
/// [`AnyUserData`]: struct.AnyUserData.html
|
||||
/// [`AnyUserData`]: crate::AnyUserData
|
||||
/// [`add_field_method_get`]: #method.add_field_method_get
|
||||
fn add_field_function_get<S, R, F>(&mut self, name: &S, function: F)
|
||||
where
|
||||
@@ -482,7 +482,7 @@ pub trait UserDataFields<'lua, T: UserData> {
|
||||
///
|
||||
/// Prefer to use [`add_field_method_set`] as it is easier to use.
|
||||
///
|
||||
/// [`AnyUserData`]: struct.AnyUserData.html
|
||||
/// [`AnyUserData`]: crate::AnyUserData
|
||||
/// [`add_field_method_set`]: #method.add_field_method_set
|
||||
fn add_field_function_set<S, A, F>(&mut self, name: &S, function: F)
|
||||
where
|
||||
@@ -578,10 +578,10 @@ pub trait UserDataFields<'lua, T: UserData> {
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`ToLua`]: trait.ToLua.html
|
||||
/// [`FromLua`]: trait.FromLua.html
|
||||
/// [`UserDataFields`]: trait.UserDataFields.html
|
||||
/// [`UserDataMethods`]: trait.UserDataMethods.html
|
||||
/// [`ToLua`]: crate::ToLua
|
||||
/// [`FromLua`]: crate::FromLua
|
||||
/// [`UserDataFields`]: crate::UserDataFields
|
||||
/// [`UserDataMethods`]: crate::UserDataMethods
|
||||
pub trait UserData: Sized {
|
||||
/// Adds custom fields specific to this userdata.
|
||||
fn add_fields<'lua, F: UserDataFields<'lua, Self>>(_fields: &mut F) {}
|
||||
@@ -718,9 +718,9 @@ impl Serialize for UserDataSerializeError {
|
||||
/// This API should only be used when necessary. Implementing [`UserData`] already allows defining
|
||||
/// methods which check the type and acquire a borrow behind the scenes.
|
||||
///
|
||||
/// [`UserData`]: trait.UserData.html
|
||||
/// [`is`]: #method.is
|
||||
/// [`borrow`]: #method.borrow
|
||||
/// [`UserData`]: crate::UserData
|
||||
/// [`is`]: crate::AnyUserData::is
|
||||
/// [`borrow`]: crate::AnyUserData::borrow
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AnyUserData<'lua>(pub(crate) LuaRef<'lua>);
|
||||
|
||||
@@ -845,7 +845,7 @@ impl<'lua> AnyUserData<'lua> {
|
||||
///
|
||||
/// For `T: UserData + 'static` returned metatable is shared among all instances of type `T`.
|
||||
///
|
||||
/// [`UserDataMetatable`]: struct.UserDataMetatable.html
|
||||
/// [`UserDataMetatable`]: crate::UserDataMetatable
|
||||
pub fn get_metatable(&self) -> Result<UserDataMetatable<'lua>> {
|
||||
self.get_raw_metatable().map(UserDataMetatable)
|
||||
}
|
||||
@@ -954,7 +954,7 @@ impl<'lua> UserDataMetatable<'lua> {
|
||||
///
|
||||
/// The pairs are wrapped in a [`Result`], since they are lazily converted to `V` type.
|
||||
///
|
||||
/// [`Result`]: type.Result.html
|
||||
/// [`Result`]: crate::Result
|
||||
pub fn pairs<V: FromLua<'lua>>(self) -> UserDataMetatablePairs<'lua, V> {
|
||||
UserDataMetatablePairs(self.0.pairs())
|
||||
}
|
||||
@@ -966,8 +966,8 @@ impl<'lua> UserDataMetatable<'lua> {
|
||||
///
|
||||
/// This struct is created by the [`UserDataMetatable::pairs`] method.
|
||||
///
|
||||
/// [`UserData`]: trait.UserData.html
|
||||
/// [`UserDataMetatable::pairs`]: struct.UserDataMetatable.html#method.pairs
|
||||
/// [`UserData`]: crate::UserData
|
||||
/// [`UserDataMetatable::pairs`]: crate::UserDataMetatable::method.pairs
|
||||
pub struct UserDataMetatablePairs<'lua, V>(TablePairs<'lua, StdString, V>);
|
||||
|
||||
impl<'lua, V> Iterator for UserDataMetatablePairs<'lua, V>
|
||||
|
||||
+2
-2
@@ -752,9 +752,9 @@ pub unsafe fn init_error_registry(state: *mut ffi::lua_State) -> Result<()> {
|
||||
(Some(error1), Some(error0)) => {
|
||||
let _ = write!(&mut (*err_buf), "\ncaused by: {}", error0);
|
||||
let s = error1.to_string();
|
||||
if let Some(traceback) = s.splitn(2, "\nstack traceback:\n").nth(1) {
|
||||
if let Some(traceback) = s.split_once("\nstack traceback:\n") {
|
||||
let _ =
|
||||
write!(&mut (*err_buf), "\nstack traceback:\n{}", traceback);
|
||||
write!(&mut (*err_buf), "\nstack traceback:\n{}", traceback.1);
|
||||
}
|
||||
}
|
||||
(Some(error1), None) => {
|
||||
|
||||
@@ -49,6 +49,7 @@ pub enum Value<'lua> {
|
||||
/// `Error` is a special builtin userdata type. When received from Lua it is implicitly cloned.
|
||||
Error(Error),
|
||||
}
|
||||
|
||||
pub use self::Value::Nil;
|
||||
|
||||
impl<'lua> Value<'lua> {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
[target.x86_64-apple-darwin]
|
||||
rustflags = ["-C", "link-args=-rdynamic"]
|
||||
|
||||
[target.aarch64-apple-darwin]
|
||||
rustflags = ["-C", "link-args=-rdynamic"]
|
||||
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
rustflags = ["-C", "link-args=-rdynamic"]
|
||||
|
||||
Reference in New Issue
Block a user