mirror of
https://github.com/mlua-rs/mlua
synced 2026-06-08 16:05:43 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 497d84828a | |||
| 0e489901a5 | |||
| 88063e756f | |||
| c8436e2b80 | |||
| 613748ec16 | |||
| 2fbd266da6 | |||
| c79b5e9cdb | |||
| 2ace892613 | |||
| c1ffd4e790 | |||
| d9c139b55f | |||
| 0c4206c97d | |||
| a985dc7a37 |
@@ -0,0 +1,68 @@
|
||||
name: Documentation (dev)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [dev]
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment
|
||||
concurrency:
|
||||
group: pages
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Documentation
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@main
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Build documentation
|
||||
env:
|
||||
RUSTDOCFLAGS: "--cfg docsrs"
|
||||
run: |
|
||||
cargo +nightly doc --no-deps \
|
||||
--features "lua55,vendored,async,send,serde,macros,anyhow,userdata-wrappers"
|
||||
|
||||
- name: Create index redirect
|
||||
run: |
|
||||
echo '<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Redirecting to mlua documentation</title>
|
||||
<meta http-equiv="refresh" content="0; URL=mlua/index.html">
|
||||
<link rel="canonical" href="mlua/index.html">
|
||||
</head>
|
||||
<body>
|
||||
<p>Redirecting to <a href="mlua/index.html">mlua documentation</a>...</p>
|
||||
</body>
|
||||
</html>' > target/doc/index.html
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
with:
|
||||
path: target/doc
|
||||
|
||||
deploy:
|
||||
name: Deploy to GitHub Pages
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
+3
-4
@@ -1,9 +1,9 @@
|
||||
[package]
|
||||
name = "mlua"
|
||||
version = "0.11.6" # remember to update mlua_derive
|
||||
version = "0.12.0-dev.1" # remember to update mlua_derive
|
||||
authors = ["Aleksandr Orlenko <zxteam@pm.me>", "kyren <catherine@kyju.org>"]
|
||||
rust-version = "1.85.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.88"
|
||||
edition = "2024"
|
||||
repository = "https://github.com/mlua-rs/mlua"
|
||||
documentation = "https://docs.rs/mlua"
|
||||
readme = "README.md"
|
||||
@@ -61,7 +61,6 @@ erased-serde = { version = "0.4", optional = true }
|
||||
serde-value = { version = "0.7", optional = true }
|
||||
parking_lot = { version = "0.12", features = ["arc_lock"] }
|
||||
anyhow = { version = "1.0", optional = true }
|
||||
rustversion = "1.0"
|
||||
libc = "0.2"
|
||||
|
||||
ffi = { package = "mlua-sys", version = "0.10.0", path = "mlua-sys" }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::time::Duration;
|
||||
|
||||
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
|
||||
use criterion::{BatchSize, Criterion, criterion_group, criterion_main};
|
||||
use tokio::runtime::Runtime;
|
||||
use tokio::task;
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
|
||||
use criterion::{BatchSize, Criterion, criterion_group, criterion_main};
|
||||
|
||||
use mlua::prelude::*;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use hyper::body::Incoming;
|
||||
use hyper_util::client::legacy::Client as HyperClient;
|
||||
use hyper_util::rt::TokioExecutor;
|
||||
|
||||
use mlua::{chunk, ExternalResult, Lua, Result, UserData, UserDataMethods};
|
||||
use mlua::{ExternalResult, Lua, Result, UserData, UserDataMethods, chunk};
|
||||
|
||||
struct BodyReader(Incoming);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use mlua::{chunk, ExternalResult, Lua, LuaSerdeExt, Result, Value};
|
||||
use mlua::{ExternalResult, Lua, LuaSerdeExt, Result, Value, chunk};
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<()> {
|
||||
|
||||
@@ -11,7 +11,7 @@ use hyper::{Request, Response};
|
||||
use hyper_util::rt::TokioIo;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
use mlua::{chunk, Error as LuaError, Function, Lua, String as LuaString, Table, UserData, UserDataMethods};
|
||||
use mlua::{Error as LuaError, Function, Lua, String as LuaString, Table, UserData, UserDataMethods, chunk};
|
||||
|
||||
/// Wrapper around incoming request that implements UserData
|
||||
struct LuaRequest(SocketAddr, Request<Incoming>);
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::net::SocketAddr;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
|
||||
use mlua::{chunk, BString, Function, Lua, UserData, UserDataMethods};
|
||||
use mlua::{BString, Function, Lua, UserData, UserDataMethods, chunk};
|
||||
|
||||
struct LuaTcpStream(TcpStream);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::f32;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use mlua::{chunk, FromLua, Function, Lua, MetaMethod, Result, UserData, UserDataMethods, Value, Variadic};
|
||||
use mlua::{FromLua, Function, Lua, MetaMethod, Result, UserData, UserDataMethods, Value, Variadic, chunk};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// You can create a new Lua state with `Lua::new()`. This loads the default Lua std library
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use mlua::{chunk, Lua, MetaMethod, Result, UserData};
|
||||
use mlua::{Lua, MetaMethod, Result, UserData, chunk};
|
||||
|
||||
#[derive(Default)]
|
||||
struct Rectangle {
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
name = "mlua-sys"
|
||||
version = "0.10.0"
|
||||
authors = ["Aleksandr Orlenko <zxteam@pm.me>"]
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.88"
|
||||
edition = "2024"
|
||||
repository = "https://github.com/mlua-rs/mlua"
|
||||
documentation = "https://docs.rs/mlua-sys"
|
||||
|
||||
+3
-3
@@ -97,7 +97,7 @@ struct BufferCursor(Buffer, usize);
|
||||
|
||||
impl io::Read for BufferCursor {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let lua = self.0 .0.lua.lock();
|
||||
let lua = self.0.0.lua.lock();
|
||||
let data = self.0.as_slice(&lua);
|
||||
if self.1 == data.len() {
|
||||
return Ok(0);
|
||||
@@ -111,7 +111,7 @@ impl io::Read for BufferCursor {
|
||||
|
||||
impl io::Write for BufferCursor {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let lua = self.0 .0.lua.lock();
|
||||
let lua = self.0.0.lua.lock();
|
||||
let data = self.0.as_slice_mut(&lua);
|
||||
if self.1 == data.len() {
|
||||
return Ok(0);
|
||||
@@ -129,7 +129,7 @@ impl io::Write for BufferCursor {
|
||||
|
||||
impl io::Seek for BufferCursor {
|
||||
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
|
||||
let lua = self.0 .0.lua.lock();
|
||||
let lua = self.0.0.lua.lock();
|
||||
let data = self.0.as_slice(&lua);
|
||||
let new_offset = match pos {
|
||||
io::SeekFrom::Start(offset) => offset as i64,
|
||||
|
||||
+67
-71
@@ -4,7 +4,6 @@ use std::ffi::CString;
|
||||
use std::io::Result as IoResult;
|
||||
use std::panic::Location;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::string::String as StdString;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::function::Function;
|
||||
@@ -20,7 +19,7 @@ pub trait AsChunk {
|
||||
/// Returns optional chunk name
|
||||
///
|
||||
/// See [`Chunk::set_name`] for possible name prefixes.
|
||||
fn name(&self) -> Option<StdString> {
|
||||
fn name(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -52,13 +51,13 @@ impl AsChunk for &str {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsChunk for StdString {
|
||||
impl AsChunk for String {
|
||||
fn source<'a>(&self) -> IoResult<Cow<'a, [u8]>> {
|
||||
Ok(Cow::Owned(self.clone().into_bytes()))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsChunk for &StdString {
|
||||
impl AsChunk for &String {
|
||||
fn source<'a>(&self) -> IoResult<Cow<'a, [u8]>>
|
||||
where
|
||||
Self: 'a,
|
||||
@@ -92,7 +91,7 @@ impl AsChunk for &Vec<u8> {
|
||||
}
|
||||
|
||||
impl AsChunk for &Path {
|
||||
fn name(&self) -> Option<StdString> {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some(format!("@{}", self.display()))
|
||||
}
|
||||
|
||||
@@ -102,7 +101,7 @@ impl AsChunk for &Path {
|
||||
}
|
||||
|
||||
impl AsChunk for PathBuf {
|
||||
fn name(&self) -> Option<StdString> {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some(format!("@{}", self.display()))
|
||||
}
|
||||
|
||||
@@ -112,7 +111,7 @@ impl AsChunk for PathBuf {
|
||||
}
|
||||
|
||||
impl<C: AsChunk + ?Sized> AsChunk for Box<C> {
|
||||
fn name(&self) -> Option<StdString> {
|
||||
fn name(&self) -> Option<String> {
|
||||
(**self).name()
|
||||
}
|
||||
|
||||
@@ -136,7 +135,7 @@ impl<C: AsChunk + ?Sized> AsChunk for Box<C> {
|
||||
#[must_use = "`Chunk`s do nothing unless one of `exec`, `eval`, `call`, or `into_function` are called on them"]
|
||||
pub struct Chunk<'a> {
|
||||
pub(crate) lua: WeakLua,
|
||||
pub(crate) name: StdString,
|
||||
pub(crate) name: String,
|
||||
pub(crate) env: Result<Option<Table>>,
|
||||
pub(crate) mode: Option<ChunkMode>,
|
||||
pub(crate) source: IoResult<Cow<'a, [u8]>>,
|
||||
@@ -160,7 +159,7 @@ pub enum CompileConstant {
|
||||
Boolean(bool),
|
||||
Number(crate::Number),
|
||||
Vector(crate::Vector),
|
||||
String(StdString),
|
||||
String(String),
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "luau", doc))]
|
||||
@@ -192,7 +191,7 @@ impl From<&str> for CompileConstant {
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "luau", doc))]
|
||||
type LibraryMemberConstantMap = HashMap<(StdString, StdString), CompileConstant>;
|
||||
type LibraryMemberConstantMap = HashMap<(String, String), CompileConstant>;
|
||||
|
||||
/// Luau compiler
|
||||
#[cfg(any(feature = "luau", doc))]
|
||||
@@ -203,14 +202,14 @@ pub struct Compiler {
|
||||
debug_level: u8,
|
||||
type_info_level: u8,
|
||||
coverage_level: u8,
|
||||
vector_lib: Option<StdString>,
|
||||
vector_ctor: Option<StdString>,
|
||||
vector_type: Option<StdString>,
|
||||
mutable_globals: Vec<StdString>,
|
||||
userdata_types: Vec<StdString>,
|
||||
libraries_with_known_members: Vec<StdString>,
|
||||
vector_lib: Option<String>,
|
||||
vector_ctor: Option<String>,
|
||||
vector_type: Option<String>,
|
||||
mutable_globals: Vec<String>,
|
||||
userdata_types: Vec<String>,
|
||||
libraries_with_known_members: Vec<String>,
|
||||
library_constants: Option<LibraryMemberConstantMap>,
|
||||
disabled_builtins: Vec<StdString>,
|
||||
disabled_builtins: Vec<String>,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "luau", doc))]
|
||||
@@ -294,7 +293,7 @@ impl Compiler {
|
||||
/// To set the library and method name, use the `lib.ctor` format.
|
||||
#[doc(hidden)]
|
||||
#[must_use]
|
||||
pub fn set_vector_ctor(mut self, ctor: impl Into<StdString>) -> Self {
|
||||
pub fn set_vector_ctor(mut self, ctor: impl Into<String>) -> Self {
|
||||
let ctor = ctor.into();
|
||||
let lib_ctor = ctor.split_once('.');
|
||||
self.vector_lib = lib_ctor.as_ref().map(|&(lib, _)| lib.to_owned());
|
||||
@@ -307,7 +306,7 @@ impl Compiler {
|
||||
/// Sets alternative vector type name for type tables, in addition to default type `vector`.
|
||||
#[doc(hidden)]
|
||||
#[must_use]
|
||||
pub fn set_vector_type(mut self, r#type: impl Into<StdString>) -> Self {
|
||||
pub fn set_vector_type(mut self, r#type: impl Into<String>) -> Self {
|
||||
self.vector_type = Some(r#type.into());
|
||||
self
|
||||
}
|
||||
@@ -316,7 +315,7 @@ impl Compiler {
|
||||
///
|
||||
/// It disables the import optimization for fields accessed through it.
|
||||
#[must_use]
|
||||
pub fn add_mutable_global(mut self, global: impl Into<StdString>) -> Self {
|
||||
pub fn add_mutable_global(mut self, global: impl Into<String>) -> Self {
|
||||
self.mutable_globals.push(global.into());
|
||||
self
|
||||
}
|
||||
@@ -325,21 +324,21 @@ impl Compiler {
|
||||
///
|
||||
/// It disables the import optimization for fields accessed through these.
|
||||
#[must_use]
|
||||
pub fn set_mutable_globals<S: Into<StdString>>(mut self, globals: impl IntoIterator<Item = S>) -> Self {
|
||||
pub fn set_mutable_globals<S: Into<String>>(mut self, globals: impl IntoIterator<Item = S>) -> Self {
|
||||
self.mutable_globals = globals.into_iter().map(|s| s.into()).collect();
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a userdata type to the list that will be included in the type information.
|
||||
#[must_use]
|
||||
pub fn add_userdata_type(mut self, r#type: impl Into<StdString>) -> Self {
|
||||
pub fn add_userdata_type(mut self, r#type: impl Into<String>) -> Self {
|
||||
self.userdata_types.push(r#type.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a list of userdata types that will be included in the type information.
|
||||
#[must_use]
|
||||
pub fn set_userdata_types<S: Into<StdString>>(mut self, types: impl IntoIterator<Item = S>) -> Self {
|
||||
pub fn set_userdata_types<S: Into<String>>(mut self, types: impl IntoIterator<Item = S>) -> Self {
|
||||
self.userdata_types = types.into_iter().map(|s| s.into()).collect();
|
||||
self
|
||||
}
|
||||
@@ -366,24 +365,21 @@ impl Compiler {
|
||||
self.libraries_with_known_members.push(lib.clone());
|
||||
}
|
||||
self.library_constants
|
||||
.get_or_insert_with(HashMap::new)
|
||||
.get_or_insert_default()
|
||||
.insert((lib, member), r#const.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a builtin that should be disabled.
|
||||
#[must_use]
|
||||
pub fn add_disabled_builtin(mut self, builtin: impl Into<StdString>) -> Self {
|
||||
pub fn add_disabled_builtin(mut self, builtin: impl Into<String>) -> Self {
|
||||
self.disabled_builtins.push(builtin.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a list of builtins that should be disabled.
|
||||
#[must_use]
|
||||
pub fn set_disabled_builtins<S: Into<StdString>>(
|
||||
mut self,
|
||||
builtins: impl IntoIterator<Item = S>,
|
||||
) -> Self {
|
||||
pub fn set_disabled_builtins<S: Into<String>>(mut self, builtins: impl IntoIterator<Item = S>) -> Self {
|
||||
self.disabled_builtins = builtins.into_iter().map(|s| s.into()).collect();
|
||||
self
|
||||
}
|
||||
@@ -477,11 +473,11 @@ impl Compiler {
|
||||
options.mutableGlobals = mutable_globals_ptr;
|
||||
options.userdataTypes = userdata_types_ptr;
|
||||
options.librariesWithKnownMembers = libraries_with_known_members_ptr;
|
||||
if let Some(map) = self.library_constants.as_ref() {
|
||||
if !self.libraries_with_known_members.is_empty() {
|
||||
LIBRARY_MEMBER_CONSTANT_MAP.with_borrow_mut(|gmap| *gmap = map.clone());
|
||||
options.libraryMemberConstantCallback = Some(library_member_constant_callback);
|
||||
}
|
||||
if let Some(map) = self.library_constants.as_ref()
|
||||
&& !self.libraries_with_known_members.is_empty()
|
||||
{
|
||||
LIBRARY_MEMBER_CONSTANT_MAP.with_borrow_mut(|gmap| *gmap = map.clone());
|
||||
options.libraryMemberConstantCallback = Some(library_member_constant_callback);
|
||||
}
|
||||
options.disabledBuiltins = disabled_builtins_ptr;
|
||||
ffi::luau_compile(source.as_ref(), options)
|
||||
@@ -490,7 +486,7 @@ impl Compiler {
|
||||
if bytecode.first() == Some(&0) {
|
||||
// The rest of the bytecode is the error message starting with `:`
|
||||
// See https://github.com/luau-lang/luau/blob/0.640/Compiler/src/Compiler.cpp#L4336
|
||||
let message = StdString::from_utf8_lossy(&bytecode[2..]).into_owned();
|
||||
let message = String::from_utf8_lossy(&bytecode[2..]).into_owned();
|
||||
return Err(Error::SyntaxError {
|
||||
incomplete_input: message.ends_with("<eof>"),
|
||||
message,
|
||||
@@ -513,7 +509,7 @@ impl Chunk<'_> {
|
||||
/// - `@` - file path (when truncation is needed, the end of the file path is kept, as this is
|
||||
/// more useful for identifying the file)
|
||||
/// - `=` - custom chunk name (when truncation is needed, the beginning of the name is kept)
|
||||
pub fn set_name(mut self, name: impl Into<StdString>) -> Self {
|
||||
pub fn set_name(mut self, name: impl Into<String>) -> Self {
|
||||
self.name = name.into();
|
||||
self
|
||||
}
|
||||
@@ -662,19 +658,19 @@ impl Chunk<'_> {
|
||||
///
|
||||
/// It does nothing if the chunk is already binary or invalid.
|
||||
fn compile(&mut self) {
|
||||
if let Ok(ref source) = self.source {
|
||||
if self.detect_mode() == ChunkMode::Text {
|
||||
#[cfg(feature = "luau")]
|
||||
if let Ok(data) = self.compiler.get_or_insert_with(Default::default).compile(source) {
|
||||
self.source = Ok(Cow::Owned(data));
|
||||
self.mode = Some(ChunkMode::Binary);
|
||||
}
|
||||
#[cfg(not(feature = "luau"))]
|
||||
if let Ok(func) = self.lua.lock().load_chunk(None, None, None, source.as_ref()) {
|
||||
let data = func.dump(false);
|
||||
self.source = Ok(Cow::Owned(data));
|
||||
self.mode = Some(ChunkMode::Binary);
|
||||
}
|
||||
if let Ok(ref source) = self.source
|
||||
&& self.detect_mode() == ChunkMode::Text
|
||||
{
|
||||
#[cfg(feature = "luau")]
|
||||
if let Ok(data) = self.compiler.get_or_insert_default().compile(source) {
|
||||
self.source = Ok(Cow::Owned(data));
|
||||
self.mode = Some(ChunkMode::Binary);
|
||||
}
|
||||
#[cfg(not(feature = "luau"))]
|
||||
if let Ok(func) = self.lua.lock().load_chunk(None, None, None, source.as_ref()) {
|
||||
let data = func.dump(false);
|
||||
self.source = Ok(Cow::Owned(data));
|
||||
self.mode = Some(ChunkMode::Binary);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -687,33 +683,33 @@ impl Chunk<'_> {
|
||||
|
||||
// Try to fetch compiled chunk from cache
|
||||
let mut text_source = None;
|
||||
if let Ok(ref source) = self.source {
|
||||
if self.detect_mode() == ChunkMode::Text {
|
||||
let lua = self.lua.lock();
|
||||
if let Some(cache) = lua.priv_app_data_ref::<ChunksCache>() {
|
||||
if let Some(data) = cache.0.get(source.as_ref()) {
|
||||
self.source = Ok(Cow::Owned(data.clone()));
|
||||
self.mode = Some(ChunkMode::Binary);
|
||||
return self;
|
||||
}
|
||||
}
|
||||
text_source = Some(source.as_ref().to_vec());
|
||||
if let Ok(ref source) = self.source
|
||||
&& self.detect_mode() == ChunkMode::Text
|
||||
{
|
||||
let lua = self.lua.lock();
|
||||
if let Some(cache) = lua.priv_app_data_ref::<ChunksCache>()
|
||||
&& let Some(data) = cache.0.get(source.as_ref())
|
||||
{
|
||||
self.source = Ok(Cow::Owned(data.clone()));
|
||||
self.mode = Some(ChunkMode::Binary);
|
||||
return self;
|
||||
}
|
||||
text_source = Some(source.as_ref().to_vec());
|
||||
}
|
||||
|
||||
// Compile and cache the chunk
|
||||
if let Some(text_source) = text_source {
|
||||
self.compile();
|
||||
if let Ok(ref binary_source) = self.source {
|
||||
if self.detect_mode() == ChunkMode::Binary {
|
||||
let lua = self.lua.lock();
|
||||
if let Some(mut cache) = lua.priv_app_data_mut::<ChunksCache>() {
|
||||
cache.0.insert(text_source, binary_source.to_vec());
|
||||
} else {
|
||||
let mut cache = ChunksCache(HashMap::new());
|
||||
cache.0.insert(text_source, binary_source.to_vec());
|
||||
lua.set_priv_app_data(cache);
|
||||
};
|
||||
if let Ok(ref binary_source) = self.source
|
||||
&& self.detect_mode() == ChunkMode::Binary
|
||||
{
|
||||
let lua = self.lua.lock();
|
||||
if let Some(mut cache) = lua.priv_app_data_mut::<ChunksCache>() {
|
||||
cache.0.insert(text_source, binary_source.to_vec());
|
||||
} else {
|
||||
let mut cache = ChunksCache(HashMap::new());
|
||||
cache.0.insert(text_source, binary_source.to_vec());
|
||||
lua.set_priv_app_data(cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -761,7 +757,7 @@ impl Chunk<'_> {
|
||||
ChunkMode::Text
|
||||
}
|
||||
|
||||
fn convert_name(name: StdString) -> Result<CString> {
|
||||
fn convert_name(name: String) -> Result<CString> {
|
||||
CString::new(name).map_err(|err| Error::runtime(format!("invalid name: {err}")))
|
||||
}
|
||||
|
||||
|
||||
+118
-196
@@ -4,16 +4,15 @@ use std::ffi::{CStr, CString, OsStr, OsString};
|
||||
use std::hash::{BuildHasher, Hash};
|
||||
use std::os::raw::c_int;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::string::String as StdString;
|
||||
use std::{mem, slice, str};
|
||||
|
||||
use bstr::{BStr, BString, ByteSlice, ByteVec};
|
||||
use bstr::{BStr, BString, ByteVec};
|
||||
use num_traits::cast;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::function::Function;
|
||||
use crate::state::{Lua, RawLua};
|
||||
use crate::string::{BorrowedBytes, BorrowedStr, String};
|
||||
use crate::string::{BorrowedBytes, BorrowedStr, LuaString};
|
||||
use crate::table::Table;
|
||||
use crate::thread::Thread;
|
||||
use crate::traits::{FromLua, IntoLua, ShortTypeName as _};
|
||||
@@ -47,14 +46,14 @@ impl FromLua for Value {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua for String {
|
||||
impl IntoLua for LuaString {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &Lua) -> Result<Value> {
|
||||
Ok(Value::String(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua for &String {
|
||||
impl IntoLua for &LuaString {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &Lua) -> Result<Value> {
|
||||
Ok(Value::String(self.clone()))
|
||||
@@ -67,16 +66,12 @@ impl IntoLua for &String {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromLua for String {
|
||||
impl FromLua for LuaString {
|
||||
#[inline]
|
||||
fn from_lua(value: Value, lua: &Lua) -> Result<String> {
|
||||
fn from_lua(value: Value, lua: &Lua) -> Result<LuaString> {
|
||||
let ty = value.type_name();
|
||||
lua.coerce_string(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: "string".to_string(),
|
||||
message: Some("expected string or number".to_string()),
|
||||
})
|
||||
.ok_or_else(|| Error::from_lua_conversion(ty, "string", "expected string or number".to_string()))
|
||||
}
|
||||
|
||||
unsafe fn from_stack(idx: c_int, lua: &RawLua) -> Result<Self> {
|
||||
@@ -84,7 +79,7 @@ impl FromLua for String {
|
||||
let type_id = ffi::lua_type(state, idx);
|
||||
if type_id == ffi::LUA_TSTRING {
|
||||
ffi::lua_xpush(state, lua.ref_thread(), idx);
|
||||
return Ok(String(lua.pop_ref_thread()));
|
||||
return Ok(LuaString(lua.pop_ref_thread()));
|
||||
}
|
||||
// Fallback to default
|
||||
Self::from_lua(lua.stack_value(idx, Some(type_id)), lua.lua())
|
||||
@@ -119,7 +114,7 @@ impl IntoLua for &BorrowedStr<'_> {
|
||||
|
||||
impl FromLua for BorrowedStr<'_> {
|
||||
fn from_lua(value: Value, lua: &Lua) -> Result<Self> {
|
||||
let s = String::from_lua(value, lua)?;
|
||||
let s = LuaString::from_lua(value, lua)?;
|
||||
let BorrowedStr { buf, _lua, .. } = BorrowedStr::try_from(&s)?;
|
||||
let buf = unsafe { mem::transmute::<&str, &'static str>(buf) };
|
||||
let borrow = Cow::Owned(s);
|
||||
@@ -127,7 +122,7 @@ impl FromLua for BorrowedStr<'_> {
|
||||
}
|
||||
|
||||
unsafe fn from_stack(idx: c_int, lua: &RawLua) -> Result<Self> {
|
||||
let s = String::from_stack(idx, lua)?;
|
||||
let s = LuaString::from_stack(idx, lua)?;
|
||||
let BorrowedStr { buf, _lua, .. } = BorrowedStr::try_from(&s)?;
|
||||
let buf = unsafe { mem::transmute::<&str, &'static str>(buf) };
|
||||
let borrow = Cow::Owned(s);
|
||||
@@ -163,7 +158,7 @@ impl IntoLua for &BorrowedBytes<'_> {
|
||||
|
||||
impl FromLua for BorrowedBytes<'_> {
|
||||
fn from_lua(value: Value, lua: &Lua) -> Result<Self> {
|
||||
let s = String::from_lua(value, lua)?;
|
||||
let s = LuaString::from_lua(value, lua)?;
|
||||
let BorrowedBytes { buf, _lua, .. } = BorrowedBytes::from(&s);
|
||||
let buf = unsafe { mem::transmute::<&[u8], &'static [u8]>(buf) };
|
||||
let borrow = Cow::Owned(s);
|
||||
@@ -171,7 +166,7 @@ impl FromLua for BorrowedBytes<'_> {
|
||||
}
|
||||
|
||||
unsafe fn from_stack(idx: c_int, lua: &RawLua) -> Result<Self> {
|
||||
let s = String::from_stack(idx, lua)?;
|
||||
let s = LuaString::from_stack(idx, lua)?;
|
||||
let BorrowedBytes { buf, _lua, .. } = BorrowedBytes::from(&s);
|
||||
let buf = unsafe { mem::transmute::<&[u8], &'static [u8]>(buf) };
|
||||
let borrow = Cow::Owned(s);
|
||||
@@ -204,11 +199,7 @@ impl FromLua for Table {
|
||||
fn from_lua(value: Value, _: &Lua) -> Result<Table> {
|
||||
match value {
|
||||
Value::Table(table) => Ok(table),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "table".to_string(),
|
||||
message: None,
|
||||
}),
|
||||
_ => Err(Error::from_lua_conversion(value.type_name(), "table", None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,11 +229,7 @@ impl FromLua for Function {
|
||||
fn from_lua(value: Value, _: &Lua) -> Result<Function> {
|
||||
match value {
|
||||
Value::Function(table) => Ok(table),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "function".to_string(),
|
||||
message: None,
|
||||
}),
|
||||
_ => Err(Error::from_lua_conversion(value.type_name(), "function", None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,11 +259,7 @@ impl FromLua for Thread {
|
||||
fn from_lua(value: Value, _: &Lua) -> Result<Thread> {
|
||||
match value {
|
||||
Value::Thread(t) => Ok(t),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "thread".to_string(),
|
||||
message: None,
|
||||
}),
|
||||
_ => Err(Error::from_lua_conversion(value.type_name(), "thread", None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -306,11 +289,7 @@ impl FromLua for AnyUserData {
|
||||
fn from_lua(value: Value, _: &Lua) -> Result<AnyUserData> {
|
||||
match value {
|
||||
Value::UserData(ud) => Ok(ud),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "userdata".to_string(),
|
||||
message: None,
|
||||
}),
|
||||
_ => Err(Error::from_lua_conversion(value.type_name(), "userdata", None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -428,11 +407,11 @@ impl FromLua for LightUserData {
|
||||
fn from_lua(value: Value, _: &Lua) -> Result<Self> {
|
||||
match value {
|
||||
Value::LightUserData(ud) => Ok(ud),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "lightuserdata".to_string(),
|
||||
message: None,
|
||||
}),
|
||||
_ => Err(Error::from_lua_conversion(
|
||||
value.type_name(),
|
||||
"lightuserdata",
|
||||
None,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -451,11 +430,7 @@ impl FromLua for crate::Vector {
|
||||
fn from_lua(value: Value, _: &Lua) -> Result<Self> {
|
||||
match value {
|
||||
Value::Vector(v) => Ok(v),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "vector".to_string(),
|
||||
message: None,
|
||||
}),
|
||||
_ => Err(Error::from_lua_conversion(value.type_name(), "vector", None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -488,16 +463,12 @@ impl FromLua for crate::Buffer {
|
||||
fn from_lua(value: Value, _: &Lua) -> Result<Self> {
|
||||
match value {
|
||||
Value::Buffer(buf) => Ok(buf),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "buffer".to_string(),
|
||||
message: None,
|
||||
}),
|
||||
_ => Err(Error::from_lua_conversion(value.type_name(), "buffer", None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua for StdString {
|
||||
impl IntoLua for String {
|
||||
#[inline]
|
||||
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
||||
#[cfg(feature = "lua55")]
|
||||
@@ -519,16 +490,14 @@ impl IntoLua for StdString {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromLua for StdString {
|
||||
impl FromLua for String {
|
||||
#[inline]
|
||||
fn from_lua(value: Value, lua: &Lua) -> Result<Self> {
|
||||
let ty = value.type_name();
|
||||
Ok(lua
|
||||
.coerce_string(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: Self::type_name(),
|
||||
message: Some("expected string or number".to_string()),
|
||||
.ok_or_else(|| {
|
||||
Error::from_lua_conversion(ty, Self::type_name(), "expected string or number".to_string())
|
||||
})?
|
||||
.to_str()?
|
||||
.to_owned())
|
||||
@@ -544,11 +513,7 @@ impl FromLua for StdString {
|
||||
let bytes = slice::from_raw_parts(data as *const u8, size);
|
||||
return str::from_utf8(bytes)
|
||||
.map(|s| s.to_owned())
|
||||
.map_err(|e| Error::FromLuaConversionError {
|
||||
from: "string",
|
||||
to: Self::type_name(),
|
||||
message: Some(e.to_string()),
|
||||
});
|
||||
.map_err(|e| Error::from_lua_conversion("string", Self::type_name(), e.to_string()));
|
||||
}
|
||||
// Fallback to default
|
||||
Self::from_lua(lua.stack_value(idx, Some(type_id)), lua.lua())
|
||||
@@ -587,10 +552,8 @@ impl FromLua for Box<str> {
|
||||
let ty = value.type_name();
|
||||
Ok(lua
|
||||
.coerce_string(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: Self::type_name(),
|
||||
message: Some("expected string or number".to_string()),
|
||||
.ok_or_else(|| {
|
||||
Error::from_lua_conversion(ty, Self::type_name(), "expected string or number".to_string())
|
||||
})?
|
||||
.to_str()?
|
||||
.to_owned()
|
||||
@@ -614,21 +577,12 @@ impl FromLua for CString {
|
||||
#[inline]
|
||||
fn from_lua(value: Value, lua: &Lua) -> Result<Self> {
|
||||
let ty = value.type_name();
|
||||
let string = lua
|
||||
.coerce_string(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: Self::type_name(),
|
||||
message: Some("expected string or number".to_string()),
|
||||
})?;
|
||||
|
||||
let string = lua.coerce_string(value)?.ok_or_else(|| {
|
||||
Error::from_lua_conversion(ty, Self::type_name(), "expected string or number".to_string())
|
||||
})?;
|
||||
match CStr::from_bytes_with_nul(&string.as_bytes_with_nul()) {
|
||||
Ok(s) => Ok(s.into()),
|
||||
Err(_) => Err(Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: Self::type_name(),
|
||||
message: Some("invalid C-style string".to_string()),
|
||||
}),
|
||||
Err(err) => Err(Error::from_lua_conversion(ty, Self::type_name(), err.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -668,10 +622,8 @@ impl FromLua for BString {
|
||||
Value::Buffer(buf) => Ok(buf.to_vec().into()),
|
||||
_ => Ok((*lua
|
||||
.coerce_string(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: Self::type_name(),
|
||||
message: Some("expected string or number".to_string()),
|
||||
.ok_or_else(|| {
|
||||
Error::from_lua_conversion(ty, Self::type_name(), "expected string or number".to_string())
|
||||
})?
|
||||
.as_bytes())
|
||||
.into()),
|
||||
@@ -722,23 +674,22 @@ impl FromLua for OsString {
|
||||
let bs = BString::from_lua(value, lua)?;
|
||||
Vec::from(bs)
|
||||
.into_os_string()
|
||||
.map_err(|err| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: "OsString".into(),
|
||||
message: Some(err.to_string()),
|
||||
})
|
||||
.map_err(|err| Error::from_lua_conversion(ty, "OsString", err.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua for &OsStr {
|
||||
#[cfg(unix)]
|
||||
#[inline]
|
||||
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
||||
let s = <[u8]>::from_os_str(self).ok_or_else(|| Error::ToLuaConversionError {
|
||||
from: "OsStr".into(),
|
||||
to: "string",
|
||||
message: Some("invalid utf-8 encoding".into()),
|
||||
})?;
|
||||
Ok(Value::String(lua.create_string(s)?))
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
Ok(Value::String(lua.create_string(self.as_bytes())?))
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
#[inline]
|
||||
fn into_lua(self, lua: &Lua) -> Result<Value> {
|
||||
self.display().to_string().into_lua(lua)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -776,34 +727,25 @@ impl FromLua for char {
|
||||
fn from_lua(value: Value, _lua: &Lua) -> Result<Self> {
|
||||
let ty = value.type_name();
|
||||
match value {
|
||||
Value::Integer(i) => {
|
||||
cast(i)
|
||||
.and_then(char::from_u32)
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: "char".to_string(),
|
||||
message: Some("integer out of range when converting to char".to_string()),
|
||||
})
|
||||
}
|
||||
Value::Integer(i) => cast(i).and_then(char::from_u32).ok_or_else(|| {
|
||||
let msg = "integer out of range when converting to char";
|
||||
Error::from_lua_conversion(ty, "char", msg.to_string())
|
||||
}),
|
||||
Value::String(s) => {
|
||||
let str = s.to_str()?;
|
||||
let mut str_iter = str.chars();
|
||||
match (str_iter.next(), str_iter.next()) {
|
||||
(Some(char), None) => Ok(char),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: "char".to_string(),
|
||||
message: Some(
|
||||
"expected string to have exactly one char when converting to char".to_string(),
|
||||
),
|
||||
}),
|
||||
_ => {
|
||||
let msg = "expected string to have exactly one char when converting to char";
|
||||
Err(Error::from_lua_conversion(ty, "char", msg.to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: Self::type_name(),
|
||||
message: Some("expected string or integer".to_string()),
|
||||
}),
|
||||
_ => {
|
||||
let msg = "expected string or integer";
|
||||
Err(Error::from_lua_conversion(ty, Self::type_name(), msg.to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -854,24 +796,14 @@ macro_rules! lua_convert_int {
|
||||
if let Some(i) = lua.coerce_integer(value.clone())? {
|
||||
cast(i)
|
||||
} else {
|
||||
cast(
|
||||
lua.coerce_number(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: stringify!($x).to_string(),
|
||||
message: Some(
|
||||
"expected number or string coercible to number".to_string(),
|
||||
),
|
||||
})?,
|
||||
)
|
||||
cast(lua.coerce_number(value)?.ok_or_else(|| {
|
||||
let msg = "expected number or string coercible to number";
|
||||
Error::from_lua_conversion(ty, stringify!($x), msg.to_string())
|
||||
})?)
|
||||
}
|
||||
}
|
||||
})
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: stringify!($x).to_string(),
|
||||
message: Some("out of range".to_owned()),
|
||||
})
|
||||
.ok_or_else(|| Error::from_lua_conversion(ty, stringify!($x), "out of range".to_string()))
|
||||
}
|
||||
|
||||
unsafe fn from_stack(idx: c_int, lua: &RawLua) -> Result<Self> {
|
||||
@@ -881,10 +813,8 @@ macro_rules! lua_convert_int {
|
||||
let mut ok = 0;
|
||||
let i = ffi::lua_tointegerx(state, idx, &mut ok);
|
||||
if ok != 0 {
|
||||
return cast(i).ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: "integer",
|
||||
to: stringify!($x).to_string(),
|
||||
message: Some("out of range".to_owned()),
|
||||
return cast(i).ok_or_else(|| {
|
||||
Error::from_lua_conversion("integer", stringify!($x), "out of range".to_string())
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -921,13 +851,10 @@ macro_rules! lua_convert_float {
|
||||
#[inline]
|
||||
fn from_lua(value: Value, lua: &Lua) -> Result<Self> {
|
||||
let ty = value.type_name();
|
||||
lua.coerce_number(value)?
|
||||
.map(|n| n as $x)
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: stringify!($x).to_string(),
|
||||
message: Some("expected number or string coercible to number".to_string()),
|
||||
})
|
||||
lua.coerce_number(value)?.map(|n| n as $x).ok_or_else(|| {
|
||||
let msg = "expected number or string coercible to number";
|
||||
Error::from_lua_conversion(ty, stringify!($x), msg.to_string())
|
||||
})
|
||||
}
|
||||
|
||||
unsafe fn from_stack(idx: c_int, lua: &RawLua) -> Result<Self> {
|
||||
@@ -987,18 +914,16 @@ where
|
||||
},
|
||||
Value::Table(table) => {
|
||||
let vec = table.sequence_values().collect::<Result<Vec<_>>>()?;
|
||||
vec.try_into()
|
||||
.map_err(|vec: Vec<T>| Error::FromLuaConversionError {
|
||||
from: "table",
|
||||
to: Self::type_name(),
|
||||
message: Some(format!("expected table of length {N}, got {}", vec.len())),
|
||||
})
|
||||
vec.try_into().map_err(|vec: Vec<T>| {
|
||||
let msg = format!("expected table of length {N}, got {}", vec.len());
|
||||
Error::from_lua_conversion("table", Self::type_name(), msg)
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
let msg = format!("expected table of length {N}");
|
||||
let err = Error::from_lua_conversion(value.type_name(), Self::type_name(), msg.to_string());
|
||||
Err(err)
|
||||
}
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: Self::type_name(),
|
||||
message: Some("expected table".to_string()),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1029,11 +954,11 @@ impl<T: FromLua> FromLua for Vec<T> {
|
||||
fn from_lua(value: Value, _lua: &Lua) -> Result<Self> {
|
||||
match value {
|
||||
Value::Table(table) => table.sequence_values().collect(),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: Self::type_name(),
|
||||
message: Some("expected table".to_string()),
|
||||
}),
|
||||
_ => Err(Error::from_lua_conversion(
|
||||
value.type_name(),
|
||||
Self::type_name(),
|
||||
"expected table".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1048,14 +973,13 @@ impl<K: Eq + Hash + IntoLua, V: IntoLua, S: BuildHasher> IntoLua for HashMap<K,
|
||||
impl<K: Eq + Hash + FromLua, V: FromLua, S: BuildHasher + Default> FromLua for HashMap<K, V, S> {
|
||||
#[inline]
|
||||
fn from_lua(value: Value, _: &Lua) -> Result<Self> {
|
||||
if let Value::Table(table) = value {
|
||||
table.pairs().collect()
|
||||
} else {
|
||||
Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: Self::type_name(),
|
||||
message: Some("expected table".to_string()),
|
||||
})
|
||||
match value {
|
||||
Value::Table(table) => table.pairs().collect(),
|
||||
_ => Err(Error::from_lua_conversion(
|
||||
value.type_name(),
|
||||
Self::type_name(),
|
||||
"expected table".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1070,14 +994,13 @@ impl<K: Ord + IntoLua, V: IntoLua> IntoLua for BTreeMap<K, V> {
|
||||
impl<K: Ord + FromLua, V: FromLua> FromLua for BTreeMap<K, V> {
|
||||
#[inline]
|
||||
fn from_lua(value: Value, _: &Lua) -> Result<Self> {
|
||||
if let Value::Table(table) = value {
|
||||
table.pairs().collect()
|
||||
} else {
|
||||
Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: Self::type_name(),
|
||||
message: Some("expected table".to_string()),
|
||||
})
|
||||
match value {
|
||||
Value::Table(table) => table.pairs().collect(),
|
||||
_ => Err(Error::from_lua_conversion(
|
||||
value.type_name(),
|
||||
Self::type_name(),
|
||||
"expected table".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1097,11 +1020,11 @@ impl<T: Eq + Hash + FromLua, S: BuildHasher + Default> FromLua for HashSet<T, S>
|
||||
match value {
|
||||
Value::Table(table) if table.raw_len() > 0 => table.sequence_values().collect(),
|
||||
Value::Table(table) => table.pairs::<T, Value>().map(|res| res.map(|(k, _)| k)).collect(),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: Self::type_name(),
|
||||
message: Some("expected table".to_string()),
|
||||
}),
|
||||
_ => Err(Error::from_lua_conversion(
|
||||
value.type_name(),
|
||||
Self::type_name(),
|
||||
"expected table".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1121,11 +1044,11 @@ impl<T: Ord + FromLua> FromLua for BTreeSet<T> {
|
||||
match value {
|
||||
Value::Table(table) if table.raw_len() > 0 => table.sequence_values().collect(),
|
||||
Value::Table(table) => table.pairs::<T, Value>().map(|res| res.map(|(k, _)| k)).collect(),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: Self::type_name(),
|
||||
message: Some("expected table".to_string()),
|
||||
}),
|
||||
_ => Err(Error::from_lua_conversion(
|
||||
value.type_name(),
|
||||
Self::type_name(),
|
||||
"expected table".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1195,11 +1118,11 @@ impl<L: FromLua, R: FromLua> FromLua for Either<L, R> {
|
||||
// Try the right type
|
||||
Err(_) => match R::from_lua(value, lua).map(Either::Right) {
|
||||
Ok(r) => Ok(r),
|
||||
Err(_) => Err(Error::FromLuaConversionError {
|
||||
from: value_type_name,
|
||||
to: Self::type_name(),
|
||||
message: None,
|
||||
}),
|
||||
Err(_) => Err(Error::from_lua_conversion(
|
||||
value_type_name,
|
||||
Self::type_name(),
|
||||
None,
|
||||
)),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1211,13 +1134,12 @@ impl<L: FromLua, R: FromLua> FromLua for Either<L, R> {
|
||||
Err(_) => match R::from_stack(idx, lua).map(Either::Right) {
|
||||
Ok(r) => Ok(r),
|
||||
Err(_) => {
|
||||
let value_type_name =
|
||||
CStr::from_ptr(ffi::lua_typename(lua.state(), ffi::lua_type(lua.state(), idx)));
|
||||
Err(Error::FromLuaConversionError {
|
||||
from: value_type_name.to_str().unwrap(),
|
||||
to: Self::type_name(),
|
||||
message: None,
|
||||
})
|
||||
let state = lua.state();
|
||||
let from_type_name = CStr::from_ptr(ffi::lua_typename(state, ffi::lua_type(state, idx)))
|
||||
.to_str()
|
||||
.unwrap_or("unknown");
|
||||
let err = Error::from_lua_conversion(from_type_name, Self::type_name(), None);
|
||||
Err(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
+32
-49
@@ -1,3 +1,9 @@
|
||||
//! Lua debugging interface.
|
||||
//!
|
||||
//! This module provides access to the Lua debug interface, allowing inspection of the call stack,
|
||||
//! and function information. The main types are [`Debug`] for accessing debug information and
|
||||
//! [`HookTriggers`] for configuring debug hooks.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::os::raw::c_int;
|
||||
|
||||
@@ -5,7 +11,7 @@ use ffi::{lua_Debug, lua_State};
|
||||
|
||||
use crate::function::Function;
|
||||
use crate::state::RawLua;
|
||||
use crate::util::{assert_stack, linenumber_to_usize, ptr_to_lossy_str, ptr_to_str, StackGuard};
|
||||
use crate::util::{StackGuard, assert_stack, linenumber_to_usize, ptr_to_lossy_str, ptr_to_str};
|
||||
|
||||
/// Contains information about currently executing Lua code.
|
||||
///
|
||||
@@ -133,12 +139,6 @@ impl<'a> Debug<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[deprecated(note = "Use `current_line` instead")]
|
||||
pub fn curr_line(&self) -> i32 {
|
||||
self.current_line().map(|n| n as i32).unwrap_or(-1)
|
||||
}
|
||||
|
||||
/// Corresponds to the `l` "what" mask. Returns the current line.
|
||||
pub fn current_line(&self) -> Option<usize> {
|
||||
unsafe {
|
||||
@@ -190,15 +190,15 @@ impl<'a> Debug<'a> {
|
||||
|
||||
#[cfg(not(feature = "luau"))]
|
||||
let stack = DebugStack {
|
||||
num_ups: (*self.ar).nups as _,
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
num_upvalues: (*self.ar).nups as _,
|
||||
#[cfg(not(any(feature = "lua51", feature = "luajit")))]
|
||||
num_params: (*self.ar).nparams as _,
|
||||
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
#[cfg(not(any(feature = "lua51", feature = "luajit")))]
|
||||
is_vararg: (*self.ar).isvararg != 0,
|
||||
};
|
||||
#[cfg(feature = "luau")]
|
||||
let stack = DebugStack {
|
||||
num_ups: (*self.ar).nupvals,
|
||||
num_upvalues: (*self.ar).nupvals,
|
||||
num_params: (*self.ar).nparams,
|
||||
is_vararg: (*self.ar).isvararg != 0,
|
||||
};
|
||||
@@ -208,6 +208,8 @@ impl<'a> Debug<'a> {
|
||||
}
|
||||
|
||||
/// Represents a specific event that triggered the hook.
|
||||
#[cfg(not(feature = "luau"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(not(feature = "luau"))))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum DebugEvent {
|
||||
Call,
|
||||
@@ -218,6 +220,9 @@ pub enum DebugEvent {
|
||||
Unknown(c_int),
|
||||
}
|
||||
|
||||
/// Contains the name information of a function in the call stack.
|
||||
///
|
||||
/// Returned by the [`Debug::names`] method.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DebugNames<'a> {
|
||||
/// A (reasonable) name of the function (`None` if the name cannot be found).
|
||||
@@ -228,6 +233,9 @@ pub struct DebugNames<'a> {
|
||||
pub name_what: Option<&'static str>,
|
||||
}
|
||||
|
||||
/// Contains the source information of a function in the call stack.
|
||||
///
|
||||
/// Returned by the [`Debug::source`] method.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DebugSource<'a> {
|
||||
/// Source of the chunk that created the function.
|
||||
@@ -243,47 +251,20 @@ pub struct DebugSource<'a> {
|
||||
pub what: &'static str,
|
||||
}
|
||||
|
||||
/// Contains stack information about a function in the call stack.
|
||||
///
|
||||
/// Returned by the [`Debug::stack`] method.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct DebugStack {
|
||||
/// Number of upvalues.
|
||||
pub num_ups: u8,
|
||||
/// Number of parameters.
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
)))
|
||||
)]
|
||||
/// The number of upvalues of the function.
|
||||
pub num_upvalues: u8,
|
||||
/// The number of parameters of the function (always 0 for C).
|
||||
#[cfg(any(not(any(feature = "lua51", feature = "luajit")), doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(not(any(feature = "lua51", feature = "luajit")))))]
|
||||
pub num_params: u8,
|
||||
/// Whether the function is a vararg function.
|
||||
#[cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
doc(cfg(any(
|
||||
feature = "lua55",
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "luau"
|
||||
)))
|
||||
)]
|
||||
/// Whether the function is a variadic function (always true for C).
|
||||
#[cfg(any(not(any(feature = "lua51", feature = "luajit")), doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(not(any(feature = "lua51", feature = "luajit")))))]
|
||||
pub is_vararg: bool,
|
||||
}
|
||||
|
||||
@@ -361,6 +342,7 @@ impl HookTriggers {
|
||||
}
|
||||
|
||||
// Compute the mask to pass to `lua_sethook`.
|
||||
#[cfg(not(feature = "luau"))]
|
||||
pub(crate) const fn mask(&self) -> c_int {
|
||||
let mut mask: c_int = 0;
|
||||
if self.on_calls {
|
||||
@@ -380,6 +362,7 @@ impl HookTriggers {
|
||||
|
||||
// Returns the `count` parameter to pass to `lua_sethook`, if applicable. Otherwise, zero is
|
||||
// returned.
|
||||
#[cfg(not(feature = "luau"))]
|
||||
pub(crate) const fn count(&self) -> c_int {
|
||||
match self.every_nth_instruction {
|
||||
Some(n) => n as c_int,
|
||||
|
||||
+30
-41
@@ -4,7 +4,6 @@ use std::io::Error as IoError;
|
||||
use std::net::AddrParseError;
|
||||
use std::result::Result as StdResult;
|
||||
use std::str::Utf8Error;
|
||||
use std::string::String as StdString;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::private::Sealed;
|
||||
@@ -22,7 +21,7 @@ pub enum Error {
|
||||
/// Syntax error while parsing Lua source code.
|
||||
SyntaxError {
|
||||
/// The error message as returned by Lua.
|
||||
message: StdString,
|
||||
message: String,
|
||||
/// `true` if the error can likely be fixed by appending more input to the source code.
|
||||
///
|
||||
/// This is useful for implementing REPLs as they can query the user for more input if this
|
||||
@@ -34,20 +33,20 @@ pub enum Error {
|
||||
/// The Lua VM returns this error when a builtin operation is performed on incompatible types.
|
||||
/// Among other things, this includes invoking operators on wrong types (such as calling or
|
||||
/// indexing a `nil` value).
|
||||
RuntimeError(StdString),
|
||||
RuntimeError(String),
|
||||
/// Lua memory error, aka `LUA_ERRMEM`
|
||||
///
|
||||
/// The Lua VM returns this error when the allocator does not return the requested memory, aka
|
||||
/// it is an out-of-memory error.
|
||||
MemoryError(StdString),
|
||||
MemoryError(String),
|
||||
/// Lua garbage collector error, aka `LUA_ERRGCMM`.
|
||||
///
|
||||
/// The Lua VM returns this error when there is an error running a `__gc` metamethod.
|
||||
#[cfg(any(feature = "lua53", feature = "lua52", doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua53", feature = "lua52"))))]
|
||||
GarbageCollectorError(StdString),
|
||||
GarbageCollectorError(String),
|
||||
/// Potentially unsafe action in safe mode.
|
||||
SafetyError(StdString),
|
||||
SafetyError(String),
|
||||
/// Memory control is not available.
|
||||
///
|
||||
/// This error can only happen when Lua state was not created by us and does not have the
|
||||
@@ -80,23 +79,14 @@ pub enum Error {
|
||||
/// (which is stored in the corresponding field).
|
||||
BadArgument {
|
||||
/// Function that was called.
|
||||
to: Option<StdString>,
|
||||
to: Option<String>,
|
||||
/// Argument position (usually starts from 1).
|
||||
pos: usize,
|
||||
/// Argument name.
|
||||
name: Option<StdString>,
|
||||
name: Option<String>,
|
||||
/// Underlying error returned when converting argument to a Lua value.
|
||||
cause: Arc<Error>,
|
||||
},
|
||||
/// A Rust value could not be converted to a Lua value.
|
||||
ToLuaConversionError {
|
||||
/// Name of the Rust type that could not be converted.
|
||||
from: String,
|
||||
/// Name of the Lua type that could not be created.
|
||||
to: &'static str,
|
||||
/// A message indicating why the conversion failed in more detail.
|
||||
message: Option<StdString>,
|
||||
},
|
||||
/// A Lua value could not be converted to the expected Rust type.
|
||||
FromLuaConversionError {
|
||||
/// Name of the Lua type that could not be converted.
|
||||
@@ -104,7 +94,7 @@ pub enum Error {
|
||||
/// Name of the Rust type that could not be created.
|
||||
to: String,
|
||||
/// A string containing more detailed error information.
|
||||
message: Option<StdString>,
|
||||
message: Option<String>,
|
||||
},
|
||||
/// [`Thread::resume`] was called on an unresumable coroutine.
|
||||
///
|
||||
@@ -154,17 +144,17 @@ pub enum Error {
|
||||
/// A [`MetaMethod`] operation is restricted (typically for `__gc` or `__metatable`).
|
||||
///
|
||||
/// [`MetaMethod`]: crate::MetaMethod
|
||||
MetaMethodRestricted(StdString),
|
||||
MetaMethodRestricted(String),
|
||||
/// A [`MetaMethod`] (eg. `__index` or `__newindex`) has invalid type.
|
||||
///
|
||||
/// [`MetaMethod`]: crate::MetaMethod
|
||||
MetaMethodTypeError {
|
||||
/// Name of the metamethod.
|
||||
method: StdString,
|
||||
method: String,
|
||||
/// Passed value type.
|
||||
type_name: &'static str,
|
||||
/// A string containing more detailed error information.
|
||||
message: Option<StdString>,
|
||||
message: Option<String>,
|
||||
},
|
||||
/// A [`RegistryKey`] produced from a different Lua state was used.
|
||||
///
|
||||
@@ -173,7 +163,7 @@ pub enum Error {
|
||||
/// A Rust callback returned `Err`, raising the contained `Error` as a Lua error.
|
||||
CallbackError {
|
||||
/// Lua call stack backtrace.
|
||||
traceback: StdString,
|
||||
traceback: String,
|
||||
/// Original error returned by the Rust code.
|
||||
cause: Arc<Error>,
|
||||
},
|
||||
@@ -185,11 +175,11 @@ pub enum Error {
|
||||
/// Serialization error.
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
|
||||
SerializeError(StdString),
|
||||
SerializeError(String),
|
||||
/// Deserialization error.
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
|
||||
DeserializeError(StdString),
|
||||
DeserializeError(String),
|
||||
/// A custom error.
|
||||
///
|
||||
/// This can be used for returning user-defined errors from callbacks.
|
||||
@@ -201,7 +191,7 @@ pub enum Error {
|
||||
/// An error with additional context.
|
||||
WithContext {
|
||||
/// A string containing additional context.
|
||||
context: StdString,
|
||||
context: String,
|
||||
/// Underlying error.
|
||||
cause: Arc<Error>,
|
||||
},
|
||||
@@ -225,7 +215,7 @@ impl fmt::Display for Error {
|
||||
}
|
||||
Error::SafetyError(msg) => {
|
||||
write!(fmt, "safety error: {msg}")
|
||||
},
|
||||
}
|
||||
Error::MemoryControlNotAvailable => {
|
||||
write!(fmt, "memory control is not available")
|
||||
}
|
||||
@@ -238,10 +228,7 @@ impl fmt::Display for Error {
|
||||
fmt,
|
||||
"out of Lua stack, too many arguments to a Lua function or too many return values from a callback"
|
||||
),
|
||||
Error::BindError => write!(
|
||||
fmt,
|
||||
"too many arguments to Function::bind"
|
||||
),
|
||||
Error::BindError => write!(fmt, "too many arguments to Function::bind"),
|
||||
Error::BadArgument { to, pos, name, cause } => {
|
||||
if let Some(name) = name {
|
||||
write!(fmt, "bad argument `{name}`")?;
|
||||
@@ -252,13 +239,6 @@ impl fmt::Display for Error {
|
||||
write!(fmt, " to `{to}`")?;
|
||||
}
|
||||
write!(fmt, ": {cause}")
|
||||
},
|
||||
Error::ToLuaConversionError { from, to, message } => {
|
||||
write!(fmt, "error converting {from} to Lua {to}")?;
|
||||
match message {
|
||||
None => Ok(()),
|
||||
Some(message) => write!(fmt, " ({message})"),
|
||||
}
|
||||
}
|
||||
Error::FromLuaConversionError { from, to, message } => {
|
||||
write!(fmt, "error converting Lua {from} to {to}")?;
|
||||
@@ -273,7 +253,11 @@ impl fmt::Display for Error {
|
||||
Error::UserDataBorrowError => write!(fmt, "error borrowing userdata"),
|
||||
Error::UserDataBorrowMutError => write!(fmt, "error mutably borrowing userdata"),
|
||||
Error::MetaMethodRestricted(method) => write!(fmt, "metamethod {method} is restricted"),
|
||||
Error::MetaMethodTypeError { method, type_name, message } => {
|
||||
Error::MetaMethodTypeError {
|
||||
method,
|
||||
type_name,
|
||||
message,
|
||||
} => {
|
||||
write!(fmt, "metamethod {method} has unsupported type {type_name}")?;
|
||||
match message {
|
||||
None => Ok(()),
|
||||
@@ -286,7 +270,11 @@ impl fmt::Display for Error {
|
||||
Error::CallbackError { cause, traceback } => {
|
||||
// Trace errors down to the root
|
||||
let (mut cause, mut full_traceback) = (cause, None);
|
||||
while let Error::CallbackError { cause: cause2, traceback: traceback2 } = &**cause {
|
||||
while let Error::CallbackError {
|
||||
cause: cause2,
|
||||
traceback: traceback2,
|
||||
} = &**cause
|
||||
{
|
||||
cause = cause2;
|
||||
full_traceback = Some(traceback2);
|
||||
}
|
||||
@@ -312,11 +300,11 @@ impl fmt::Display for Error {
|
||||
#[cfg(feature = "serde")]
|
||||
Error::SerializeError(err) => {
|
||||
write!(fmt, "serialize error: {err}")
|
||||
},
|
||||
}
|
||||
#[cfg(feature = "serde")]
|
||||
Error::DeserializeError(err) => {
|
||||
write!(fmt, "deserialize error: {err}")
|
||||
},
|
||||
}
|
||||
Error::ExternalError(err) => err.fmt(fmt),
|
||||
Error::WithContext { context, cause } => {
|
||||
writeln!(fmt, "{context}")?;
|
||||
@@ -394,6 +382,7 @@ impl Error {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn from_lua_conversion(
|
||||
from: &'static str,
|
||||
to: impl ToString,
|
||||
|
||||
+85
-2
@@ -1,3 +1,84 @@
|
||||
//! Lua function handling.
|
||||
//!
|
||||
//! This module provides types for working with Lua functions from Rust, including
|
||||
//! both Lua-defined functions and native Rust callbacks.
|
||||
//!
|
||||
//! # Main Types
|
||||
//!
|
||||
//! - [`Function`] - A handle to a Lua function that can be called from Rust.
|
||||
//! - [`FunctionInfo`] - Debug information about a function (name, source, line numbers, etc.).
|
||||
//! - [`CoverageInfo`] - Code coverage data for Luau functions (requires `luau` feature).
|
||||
//!
|
||||
//! # Calling Functions
|
||||
//!
|
||||
//! Use [`Function::call`] to invoke a Lua function synchronously:
|
||||
//!
|
||||
//! ```
|
||||
//! # use mlua::{Function, Lua, Result};
|
||||
//! # fn main() -> Result<()> {
|
||||
//! let lua = Lua::new();
|
||||
//!
|
||||
//! // Get a built-in function
|
||||
//! let print: Function = lua.globals().get("print")?;
|
||||
//! print.call::<()>("Hello from Rust!")?;
|
||||
//!
|
||||
//! // Call a function that returns values
|
||||
//! let tonumber: Function = lua.globals().get("tonumber")?;
|
||||
//! let n: i32 = tonumber.call("42")?;
|
||||
//! assert_eq!(n, 42);
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! For asynchronous execution, use `Function::call_async` (requires `async` feature):
|
||||
//!
|
||||
//! ```ignore
|
||||
//! let result: String = my_async_func.call_async(args).await?;
|
||||
//! ```
|
||||
//!
|
||||
//! # Creating Functions
|
||||
//!
|
||||
//! Functions can be created from Rust closures using [`Lua::create_function`]:
|
||||
//!
|
||||
//! ```
|
||||
//! # use mlua::{Lua, Result};
|
||||
//! # fn main() -> Result<()> {
|
||||
//! let lua = Lua::new();
|
||||
//!
|
||||
//! let greet = lua.create_function(|_, name: String| {
|
||||
//! Ok(format!("Hello, {}!", name))
|
||||
//! })?;
|
||||
//!
|
||||
//! lua.globals().set("greet", greet)?;
|
||||
//! let result: String = lua.load(r#"greet("World")"#).eval()?;
|
||||
//! assert_eq!(result, "Hello, World!");
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! For simpler cases, use [`Function::wrap`] or [`Function::wrap_raw`] to convert a Rust function
|
||||
//! directly:
|
||||
//!
|
||||
//! ```
|
||||
//! # use mlua::{Function, Lua, Result};
|
||||
//! # fn main() -> Result<()> {
|
||||
//! let lua = Lua::new();
|
||||
//!
|
||||
//! fn add(a: i32, b: i32) -> i32 { a + b }
|
||||
//!
|
||||
//! lua.globals().set("add", Function::wrap_raw(add))?;
|
||||
//! let sum: i32 = lua.load("add(2, 3)").eval()?;
|
||||
//! assert_eq!(sum, 5);
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! # Function Environments
|
||||
//!
|
||||
//! Lua functions have an associated environment table that determines how global
|
||||
//! variables are resolved. Use [`Function::environment`] and [`Function::set_environment`]
|
||||
//! to inspect or modify this environment.
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::os::raw::{c_int, c_void};
|
||||
use std::{mem, ptr, slice};
|
||||
@@ -8,7 +89,7 @@ use crate::table::Table;
|
||||
use crate::traits::{FromLuaMulti, IntoLua, IntoLuaMulti, LuaNativeFn, LuaNativeFnMut};
|
||||
use crate::types::{Callback, LuaType, MaybeSend, ValueRef};
|
||||
use crate::util::{
|
||||
assert_stack, check_stack, linenumber_to_usize, pop_error, ptr_to_lossy_str, ptr_to_str, StackGuard,
|
||||
StackGuard, assert_stack, check_stack, linenumber_to_usize, pop_error, ptr_to_lossy_str, ptr_to_str,
|
||||
};
|
||||
use crate::value::Value;
|
||||
|
||||
@@ -18,7 +99,7 @@ use {
|
||||
crate::traits::LuaNativeAsyncFn,
|
||||
crate::types::AsyncCallback,
|
||||
std::future::{self, Future},
|
||||
std::pin::{pin, Pin},
|
||||
std::pin::{Pin, pin},
|
||||
std::task::{Context, Poll},
|
||||
};
|
||||
|
||||
@@ -681,7 +762,9 @@ impl LuaType for Function {
|
||||
const TYPE_ID: c_int = ffi::LUA_TFUNCTION;
|
||||
}
|
||||
|
||||
/// Future for asynchronous function calls.
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct AsyncCallFuture<R: FromLuaMulti>(Result<AsyncThread<R>>);
|
||||
|
||||
|
||||
+7
-10
@@ -66,7 +66,6 @@
|
||||
// warnings at all.
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![cfg_attr(not(send), allow(clippy::arc_with_non_send_sync))]
|
||||
#![allow(clippy::ptr_eq)]
|
||||
#![allow(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
#[macro_use]
|
||||
@@ -75,9 +74,7 @@ mod macros;
|
||||
mod buffer;
|
||||
mod chunk;
|
||||
mod conversion;
|
||||
mod debug;
|
||||
mod error;
|
||||
mod function;
|
||||
#[cfg(any(feature = "luau", doc))]
|
||||
mod luau;
|
||||
mod memory;
|
||||
@@ -86,7 +83,6 @@ mod scope;
|
||||
mod state;
|
||||
mod stdlib;
|
||||
mod string;
|
||||
mod table;
|
||||
mod thread;
|
||||
mod traits;
|
||||
mod types;
|
||||
@@ -95,21 +91,23 @@ mod util;
|
||||
mod value;
|
||||
mod vector;
|
||||
|
||||
pub mod debug;
|
||||
pub mod function;
|
||||
pub mod prelude;
|
||||
pub mod table;
|
||||
|
||||
pub use bstr::BString;
|
||||
pub use ffi::{self, lua_CFunction, lua_State};
|
||||
|
||||
pub use crate::chunk::{AsChunk, Chunk, ChunkMode};
|
||||
pub use crate::debug::{Debug, DebugEvent, DebugNames, DebugSource, DebugStack};
|
||||
pub use crate::error::{Error, ErrorContext, ExternalError, ExternalResult, Result};
|
||||
pub use crate::function::{Function, FunctionInfo};
|
||||
pub use crate::function::Function;
|
||||
pub use crate::multi::{MultiValue, Variadic};
|
||||
pub use crate::scope::Scope;
|
||||
pub use crate::state::{GCMode, Lua, LuaOptions, WeakLua};
|
||||
pub use crate::stdlib::StdLib;
|
||||
pub use crate::string::{BorrowedBytes, BorrowedStr, String};
|
||||
pub use crate::table::{Table, TablePairs, TableSequence};
|
||||
pub use crate::string::{BorrowedBytes, BorrowedStr, LuaString, LuaString as String};
|
||||
pub use crate::table::Table;
|
||||
pub use crate::thread::{Thread, ThreadStatus};
|
||||
pub use crate::traits::{
|
||||
FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, LuaNativeFn, LuaNativeFnMut, ObjectLike,
|
||||
@@ -131,7 +129,6 @@ pub use crate::debug::HookTriggers;
|
||||
pub use crate::{
|
||||
buffer::Buffer,
|
||||
chunk::{CompileConstant, Compiler},
|
||||
function::CoverageInfo,
|
||||
luau::{HeapDump, NavigateError, Require, TextRequirer},
|
||||
vector::Vector,
|
||||
};
|
||||
@@ -143,7 +140,7 @@ pub use crate::{thread::AsyncThread, traits::LuaNativeAsyncFn};
|
||||
#[cfg(feature = "serde")]
|
||||
#[doc(inline)]
|
||||
pub use crate::{
|
||||
serde::{de::Options as DeserializeOptions, ser::Options as SerializeOptions, LuaSerdeExt},
|
||||
serde::{LuaSerdeExt, de::Options as DeserializeOptions, ser::Options as SerializeOptions},
|
||||
value::SerializableValue,
|
||||
};
|
||||
|
||||
|
||||
+13
-13
@@ -79,10 +79,10 @@ impl HeapDump {
|
||||
let mut size_by_type = HashMap::new();
|
||||
let objects = self.data["objects"].as_object()?;
|
||||
for obj in objects.values() {
|
||||
if let Some(cat_id) = category_id {
|
||||
if obj["cat"].as_i64()? != cat_id {
|
||||
continue;
|
||||
}
|
||||
if let Some(cat_id) = category_id
|
||||
&& obj["cat"].as_i64()? != cat_id
|
||||
{
|
||||
continue;
|
||||
}
|
||||
update_size(&mut size_by_type, obj["type"].as_str()?, obj["size"].as_u64()?);
|
||||
}
|
||||
@@ -123,18 +123,18 @@ impl HeapDump {
|
||||
if obj["type"] != "userdata" {
|
||||
continue;
|
||||
}
|
||||
if let Some(cat_id) = category_id {
|
||||
if obj["cat"].as_i64()? != cat_id {
|
||||
continue;
|
||||
}
|
||||
if let Some(cat_id) = category_id
|
||||
&& obj["cat"].as_i64()? != cat_id
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Determine userdata type from metatable
|
||||
let mut ud_type = "unknown";
|
||||
if let Some(metatable_addr) = obj["metatable"].as_str() {
|
||||
if let Some(t) = get_key(objects, &objects[metatable_addr], "__type") {
|
||||
ud_type = t;
|
||||
}
|
||||
if let Some(metatable_addr) = obj["metatable"].as_str()
|
||||
&& let Some(t) = get_key(objects, &objects[metatable_addr], "__type")
|
||||
{
|
||||
ud_type = t;
|
||||
}
|
||||
update_size(&mut size_by_userdata, ud_type, obj["size"].as_u64()?);
|
||||
}
|
||||
@@ -155,7 +155,7 @@ impl HeapDump {
|
||||
|
||||
/// Updates the size mapping for a given key.
|
||||
fn update_size<K: Eq + Hash>(size_type: &mut HashMap<K, (usize, u64)>, key: K, size: u64) {
|
||||
let (ref mut count, ref mut total_size) = size_type.entry(key).or_insert((0, 0));
|
||||
let (count, total_size) = size_type.entry(key).or_insert((0, 0));
|
||||
*count += 1;
|
||||
*total_size += size;
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ use std::ptr;
|
||||
use crate::chunk::ChunkMode;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::function::Function;
|
||||
use crate::state::{callback_error_ext, ExtraData, Lua};
|
||||
use crate::state::{ExtraData, Lua, callback_error_ext};
|
||||
use crate::traits::{FromLuaMulti, IntoLua};
|
||||
use crate::types::MaybeSend;
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ use std::{fmt, mem, ptr};
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::function::Function;
|
||||
use crate::state::{callback_error_ext, Lua};
|
||||
use crate::state::{Lua, callback_error_ext};
|
||||
use crate::table::Table;
|
||||
use crate::types::MaybeSend;
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@ impl TextRequirer {
|
||||
}
|
||||
|
||||
fn normalize_chunk_name(chunk_name: &str) -> &str {
|
||||
if let Some((path, line)) = chunk_name.rsplit_once(':') {
|
||||
if line.parse::<u32>().is_ok() {
|
||||
return path;
|
||||
}
|
||||
if let Some((path, line)) = chunk_name.rsplit_once(':')
|
||||
&& line.parse::<u32>().is_ok()
|
||||
{
|
||||
return path;
|
||||
}
|
||||
chunk_name
|
||||
}
|
||||
|
||||
@@ -28,9 +28,7 @@ impl MemoryState {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "luau"))]
|
||||
#[rustversion::since(1.85)]
|
||||
#[inline]
|
||||
#[allow(clippy::incompatible_msrv)]
|
||||
pub(crate) unsafe fn get(state: *mut ffi::lua_State) -> *mut Self {
|
||||
let mut mem_state = ptr::null_mut();
|
||||
if !ptr::fn_addr_eq(ffi::lua_getallocf(state, &mut mem_state), ALLOCATOR) {
|
||||
@@ -39,17 +37,6 @@ impl MemoryState {
|
||||
mem_state as *mut MemoryState
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "luau"))]
|
||||
#[rustversion::before(1.85)]
|
||||
#[inline]
|
||||
pub(crate) unsafe fn get(state: *mut ffi::lua_State) -> *mut Self {
|
||||
let mut mem_state = ptr::null_mut();
|
||||
if ffi::lua_getallocf(state, &mut mem_state) != ALLOCATOR {
|
||||
mem_state = ptr::null_mut();
|
||||
}
|
||||
mem_state as *mut MemoryState
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn used_memory(&self) -> usize {
|
||||
self.used_memory as usize
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
use std::collections::{vec_deque, VecDeque};
|
||||
use std::collections::{VecDeque, vec_deque};
|
||||
use std::iter::FromIterator;
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
+7
-8
@@ -5,16 +5,16 @@ pub use crate::{
|
||||
AnyUserData as LuaAnyUserData, BorrowedBytes as LuaBorrowedBytes, BorrowedStr as LuaBorrowedStr,
|
||||
Chunk as LuaChunk, Either as LuaEither, Error as LuaError, ErrorContext as LuaErrorContext,
|
||||
ExternalError as LuaExternalError, ExternalResult as LuaExternalResult, FromLua, FromLuaMulti,
|
||||
Function as LuaFunction, FunctionInfo as LuaFunctionInfo, GCMode as LuaGCMode, Integer as LuaInteger,
|
||||
IntoLua, IntoLuaMulti, LightUserData as LuaLightUserData, Lua, LuaNativeFn, LuaNativeFnMut, LuaOptions,
|
||||
Function as LuaFunction, GCMode as LuaGCMode, Integer as LuaInteger, IntoLua, IntoLuaMulti,
|
||||
LightUserData as LuaLightUserData, Lua, LuaNativeFn, LuaNativeFnMut, LuaOptions, LuaString,
|
||||
MetaMethod as LuaMetaMethod, MultiValue as LuaMultiValue, Nil as LuaNil, Number as LuaNumber,
|
||||
ObjectLike as LuaObjectLike, RegistryKey as LuaRegistryKey, Result as LuaResult, StdLib as LuaStdLib,
|
||||
String as LuaString, Table as LuaTable, TablePairs as LuaTablePairs, TableSequence as LuaTableSequence,
|
||||
Thread as LuaThread, ThreadStatus as LuaThreadStatus, UserData as LuaUserData,
|
||||
Table as LuaTable, Thread as LuaThread, ThreadStatus as LuaThreadStatus, UserData as LuaUserData,
|
||||
UserDataFields as LuaUserDataFields, UserDataMetatable as LuaUserDataMetatable,
|
||||
UserDataMethods as LuaUserDataMethods, UserDataRef as LuaUserDataRef,
|
||||
UserDataRefMut as LuaUserDataRefMut, UserDataRegistry as LuaUserDataRegistry, Value as LuaValue,
|
||||
Variadic as LuaVariadic, VmState as LuaVmState, WeakLua,
|
||||
Variadic as LuaVariadic, VmState as LuaVmState, WeakLua, function::FunctionInfo as LuaFunctionInfo,
|
||||
table::TablePairs as LuaTablePairs, table::TableSequence as LuaTableSequence,
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "luau"))]
|
||||
@@ -24,9 +24,8 @@ pub use crate::HookTriggers as LuaHookTriggers;
|
||||
#[cfg(feature = "luau")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::{
|
||||
CompileConstant as LuaCompileConstant, CoverageInfo as LuaCoverageInfo,
|
||||
NavigateError as LuaNavigateError, Require as LuaRequire, TextRequirer as LuaTextRequirer,
|
||||
Vector as LuaVector,
|
||||
CompileConstant as LuaCompileConstant, NavigateError as LuaNavigateError, Require as LuaRequire,
|
||||
TextRequirer as LuaTextRequirer, Vector as LuaVector,
|
||||
};
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ use crate::state::{Lua, LuaGuard, RawLua};
|
||||
use crate::traits::{FromLuaMulti, IntoLuaMulti};
|
||||
use crate::types::{Callback, CallbackUpvalue, ScopedCallback, ValueRef};
|
||||
use crate::userdata::{AnyUserData, UserData, UserDataRegistry, UserDataStorage};
|
||||
use crate::util::{self, check_stack, get_metatable_ptr, get_userdata, take_userdata, StackGuard};
|
||||
use crate::util::{self, StackGuard, check_stack, get_metatable_ptr, get_userdata, take_userdata};
|
||||
|
||||
/// Constructed by the [`Lua::scope`] method, allows temporarily creating Lua userdata and
|
||||
/// callbacks that are not required to be `Send` or `'static`.
|
||||
|
||||
+3
-4
@@ -4,7 +4,6 @@ use std::cell::RefCell;
|
||||
use std::os::raw::c_void;
|
||||
use std::rc::Rc;
|
||||
use std::result::Result as StdResult;
|
||||
use std::string::String as StdString;
|
||||
|
||||
use rustc_hash::FxHashSet;
|
||||
use serde::de::{self, IntoDeserializer};
|
||||
@@ -243,14 +242,14 @@ impl<'de> serde::Deserializer<'de> for Deserializer {
|
||||
Value::Table(table) => {
|
||||
let _guard = RecursionGuard::new(&table, &self.visited);
|
||||
|
||||
let mut iter = table.pairs::<StdString, Value>();
|
||||
let mut iter = table.pairs::<String, Value>();
|
||||
let (variant, value) = match iter.next() {
|
||||
Some(v) => v?,
|
||||
None => {
|
||||
return Err(de::Error::invalid_value(
|
||||
de::Unexpected::Map,
|
||||
&"map with a single key",
|
||||
))
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -621,7 +620,7 @@ impl<'de> de::MapAccess<'de> for MapDeserializer<'_> {
|
||||
}
|
||||
|
||||
struct EnumDeserializer {
|
||||
variant: StdString,
|
||||
variant: String,
|
||||
value: Option<Value>,
|
||||
options: Options,
|
||||
visited: Rc<RefCell<FxHashSet<*const c_void>>>,
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
//! Serialize a Rust data structure into Lua value.
|
||||
|
||||
use serde::{ser, Serialize};
|
||||
use serde::{Serialize, ser};
|
||||
|
||||
use super::LuaSerdeExt;
|
||||
use crate::error::{Error, Result};
|
||||
@@ -531,10 +531,10 @@ impl ser::SerializeStruct for SerializeStruct<'_> {
|
||||
Some(table @ Value::Table(_)) => Ok(table),
|
||||
Some(value @ Value::String(_)) if self.options.detect_serde_json_arbitrary_precision => {
|
||||
let number_s = value.to_string()?;
|
||||
if number_s.contains(['.', 'e', 'E']) {
|
||||
if let Ok(number) = number_s.parse().map(Value::Number) {
|
||||
return Ok(number);
|
||||
}
|
||||
if number_s.contains(['.', 'e', 'E'])
|
||||
&& let Ok(number) = number_s.parse().map(Value::Number)
|
||||
{
|
||||
return Ok(number);
|
||||
}
|
||||
Ok(number_s
|
||||
.parse()
|
||||
|
||||
+16
-25
@@ -15,7 +15,7 @@ use crate::memory::MemoryState;
|
||||
use crate::multi::MultiValue;
|
||||
use crate::scope::Scope;
|
||||
use crate::stdlib::StdLib;
|
||||
use crate::string::String;
|
||||
use crate::string::LuaString;
|
||||
use crate::table::Table;
|
||||
use crate::thread::Thread;
|
||||
use crate::traits::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti};
|
||||
@@ -24,7 +24,7 @@ use crate::types::{
|
||||
ReentrantMutexGuard, RegistryKey, VmState, XRc, XWeak,
|
||||
};
|
||||
use crate::userdata::{AnyUserData, UserData, UserDataProxy, UserDataRegistry, UserDataStorage};
|
||||
use crate::util::{assert_stack, check_stack, protect_lua_closure, push_string, rawset_field, StackGuard};
|
||||
use crate::util::{StackGuard, assert_stack, check_stack, protect_lua_closure, push_string, rawset_field};
|
||||
use crate::value::{Nil, Value};
|
||||
|
||||
#[cfg(not(feature = "luau"))]
|
||||
@@ -855,7 +855,6 @@ impl Lua {
|
||||
{
|
||||
use std::ffi::CStr;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use std::string::String as StdString;
|
||||
|
||||
unsafe extern "C-unwind" fn warn_proc(ud: *mut c_void, msg: *const c_char, tocont: c_int) {
|
||||
let extra = ud as *mut ExtraData;
|
||||
@@ -865,7 +864,7 @@ impl Lua {
|
||||
if XRc::strong_count(&warn_callback) > 2 {
|
||||
return Ok(());
|
||||
}
|
||||
let msg = StdString::from_utf8_lossy(CStr::from_ptr(msg).to_bytes());
|
||||
let msg = String::from_utf8_lossy(CStr::from_ptr(msg).to_bytes());
|
||||
warn_callback((*extra).lua(), &msg, tocont != 0)
|
||||
});
|
||||
}
|
||||
@@ -936,7 +935,7 @@ impl Lua {
|
||||
///
|
||||
/// The `msg` parameter, if provided, is added at the beginning of the traceback.
|
||||
/// The `level` parameter works the same way as in [`Lua::inspect_stack`].
|
||||
pub fn traceback(&self, msg: Option<&str>, level: usize) -> Result<String> {
|
||||
pub fn traceback(&self, msg: Option<&str>, level: usize) -> Result<LuaString> {
|
||||
let lua = self.lock();
|
||||
unsafe {
|
||||
check_stack(lua.state(), 3)?;
|
||||
@@ -948,7 +947,7 @@ impl Lua {
|
||||
// `protect_lua` adds it's own call frame, so we need to increase level by 1
|
||||
ffi::luaL_traceback(state, state, msg, (level + 1) as c_int);
|
||||
})?;
|
||||
Ok(String(lua.pop_ref()))
|
||||
Ok(LuaString(lua.pop_ref()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1127,7 +1126,7 @@ impl Lua {
|
||||
#[cfg(not(feature = "luau"))]
|
||||
let _ = step_size; // Ignored
|
||||
|
||||
return GCMode::Incremental;
|
||||
GCMode::Incremental
|
||||
}
|
||||
|
||||
#[cfg(feature = "lua55")]
|
||||
@@ -1205,10 +1204,10 @@ impl Lua {
|
||||
#[doc(hidden)]
|
||||
#[allow(clippy::result_unit_err)]
|
||||
pub fn set_fflag(name: &str, enabled: bool) -> StdResult<(), ()> {
|
||||
if let Ok(name) = std::ffi::CString::new(name) {
|
||||
if unsafe { ffi::luau_setfflag(name.as_ptr(), enabled as c_int) != 0 } {
|
||||
return Ok(());
|
||||
}
|
||||
if let Ok(name) = std::ffi::CString::new(name)
|
||||
&& unsafe { ffi::luau_setfflag(name.as_ptr(), enabled as c_int) != 0 }
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
@@ -1248,7 +1247,7 @@ impl Lua {
|
||||
/// Lua strings can be arbitrary `[u8]` data including embedded nulls, so in addition to `&str`
|
||||
/// and `&String`, you can also pass plain `&[u8]` here.
|
||||
#[inline]
|
||||
pub fn create_string(&self, s: impl AsRef<[u8]>) -> Result<String> {
|
||||
pub fn create_string(&self, s: impl AsRef<[u8]>) -> Result<LuaString> {
|
||||
unsafe { self.lock().create_string(s.as_ref()) }
|
||||
}
|
||||
|
||||
@@ -1259,7 +1258,7 @@ impl Lua {
|
||||
#[cfg(feature = "lua55")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "lua55")))]
|
||||
#[inline]
|
||||
pub fn create_external_string(&self, s: impl Into<Vec<u8>>) -> Result<String> {
|
||||
pub fn create_external_string(&self, s: impl Into<Vec<u8>>) -> Result<LuaString> {
|
||||
unsafe { self.lock().create_external_string(s.into()) }
|
||||
}
|
||||
|
||||
@@ -1741,7 +1740,7 @@ impl Lua {
|
||||
///
|
||||
/// To succeed, the value must be a string (in which case this is a no-op), an integer, or a
|
||||
/// number.
|
||||
pub fn coerce_string(&self, v: Value) -> Result<Option<String>> {
|
||||
pub fn coerce_string(&self, v: Value) -> Result<Option<LuaString>> {
|
||||
Ok(match v {
|
||||
Value::String(s) => Some(s),
|
||||
v => unsafe {
|
||||
@@ -1759,7 +1758,7 @@ impl Lua {
|
||||
})?
|
||||
};
|
||||
if !res.is_null() {
|
||||
Some(String(lua.pop_ref()))
|
||||
Some(LuaString(lua.pop_ref()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -1785,11 +1784,7 @@ impl Lua {
|
||||
lua.push_value(&v)?;
|
||||
let mut isint = 0;
|
||||
let i = ffi::lua_tointegerx(state, -1, &mut isint);
|
||||
if isint == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(i)
|
||||
}
|
||||
if isint == 0 { None } else { Some(i) }
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1811,11 +1806,7 @@ impl Lua {
|
||||
lua.push_value(&v)?;
|
||||
let mut isnum = 0;
|
||||
let n = ffi::lua_tonumberx(state, -1, &mut isnum);
|
||||
if isnum == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(n)
|
||||
}
|
||||
if isnum == 0 { None } else { Some(n) }
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ use crate::state::RawLua;
|
||||
use crate::stdlib::StdLib;
|
||||
use crate::types::{AppData, ReentrantMutex, XRc};
|
||||
use crate::userdata::RawUserDataRegistry;
|
||||
use crate::util::{get_internal_metatable, push_internal_userdata, TypeKey, WrappedFailure};
|
||||
use crate::util::{TypeKey, WrappedFailure, get_internal_metatable, push_internal_userdata};
|
||||
|
||||
#[cfg(any(feature = "luau", doc))]
|
||||
use crate::chunk::Compiler;
|
||||
|
||||
+24
-26
@@ -10,10 +10,10 @@ use std::sync::Arc;
|
||||
use crate::chunk::ChunkMode;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::function::Function;
|
||||
use crate::memory::{MemoryState, ALLOCATOR};
|
||||
use crate::memory::{ALLOCATOR, MemoryState};
|
||||
use crate::state::util::callback_error_ext;
|
||||
use crate::stdlib::StdLib;
|
||||
use crate::string::String;
|
||||
use crate::string::LuaString;
|
||||
use crate::table::Table;
|
||||
use crate::thread::Thread;
|
||||
use crate::traits::IntoLua;
|
||||
@@ -22,14 +22,14 @@ use crate::types::{
|
||||
LuaType, MaybeSend, ReentrantMutex, RegistryKey, ValueRef, XRc,
|
||||
};
|
||||
use crate::userdata::{
|
||||
init_userdata_metatable, AnyUserData, MetaMethod, RawUserDataRegistry, UserData, UserDataRegistry,
|
||||
UserDataStorage,
|
||||
AnyUserData, MetaMethod, RawUserDataRegistry, UserData, UserDataRegistry, UserDataStorage,
|
||||
init_userdata_metatable,
|
||||
};
|
||||
use crate::util::{
|
||||
assert_stack, check_stack, get_destructed_userdata_metatable, get_internal_userdata, get_main_state,
|
||||
get_metatable_ptr, get_userdata, init_error_registry, init_internal_metatable, pop_error,
|
||||
push_internal_userdata, push_string, push_table, push_userdata, rawset_field, safe_pcall, safe_xpcall,
|
||||
short_type_name, StackGuard, WrappedFailure,
|
||||
StackGuard, WrappedFailure, assert_stack, check_stack, get_destructed_userdata_metatable,
|
||||
get_internal_userdata, get_main_state, get_metatable_ptr, get_userdata, init_error_registry,
|
||||
init_internal_metatable, pop_error, push_internal_userdata, push_string, push_table, push_userdata,
|
||||
rawset_field, safe_pcall, safe_xpcall, short_type_name,
|
||||
};
|
||||
use crate::value::{Nil, Value};
|
||||
|
||||
@@ -516,34 +516,34 @@ impl RawLua {
|
||||
}
|
||||
|
||||
/// See [`Lua::create_string`]
|
||||
pub(crate) unsafe fn create_string(&self, s: &[u8]) -> Result<String> {
|
||||
pub(crate) unsafe fn create_string(&self, s: &[u8]) -> Result<LuaString> {
|
||||
let state = self.state();
|
||||
if self.unlikely_memory_error() {
|
||||
push_string(state, s, false)?;
|
||||
return Ok(String(self.pop_ref()));
|
||||
return Ok(LuaString(self.pop_ref()));
|
||||
}
|
||||
|
||||
let _sg = StackGuard::new(state);
|
||||
check_stack(state, 3)?;
|
||||
push_string(state, s, true)?;
|
||||
Ok(String(self.pop_ref()))
|
||||
Ok(LuaString(self.pop_ref()))
|
||||
}
|
||||
|
||||
/// Creates an external string, that is, a string that uses memory not managed by Lua.
|
||||
///
|
||||
/// Modifies the input data to add `\0` terminator.
|
||||
#[cfg(feature = "lua55")]
|
||||
pub(crate) unsafe fn create_external_string(&self, bytes: Vec<u8>) -> Result<String> {
|
||||
pub(crate) unsafe fn create_external_string(&self, bytes: Vec<u8>) -> Result<LuaString> {
|
||||
let state = self.state();
|
||||
if self.unlikely_memory_error() {
|
||||
crate::util::push_external_string(state, bytes, false)?;
|
||||
return Ok(String(self.pop_ref()));
|
||||
return Ok(LuaString(self.pop_ref()));
|
||||
}
|
||||
|
||||
let _sg = StackGuard::new(state);
|
||||
check_stack(state, 3)?;
|
||||
crate::util::push_external_string(state, bytes, true)?;
|
||||
Ok(String(self.pop_ref()))
|
||||
Ok(LuaString(self.pop_ref()))
|
||||
}
|
||||
|
||||
#[cfg(feature = "luau")]
|
||||
@@ -681,10 +681,10 @@ impl RawLua {
|
||||
#[cfg(feature = "async")]
|
||||
pub(crate) unsafe fn recycle_thread(&self, thread: &mut Thread) {
|
||||
let extra = &mut *self.extra.get();
|
||||
if extra.thread_pool.len() < extra.thread_pool.capacity() {
|
||||
if let Some(index) = thread.0.index_count.take() {
|
||||
extra.thread_pool.push(index);
|
||||
}
|
||||
if extra.thread_pool.len() < extra.thread_pool.capacity()
|
||||
&& let Some(index) = thread.0.index_count.take()
|
||||
{
|
||||
extra.thread_pool.push(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -824,7 +824,7 @@ impl RawLua {
|
||||
|
||||
ffi::LUA_TSTRING => {
|
||||
ffi::lua_xpush(state, self.ref_thread(), idx);
|
||||
Value::String(String(self.pop_ref_thread()))
|
||||
Value::String(LuaString(self.pop_ref_thread()))
|
||||
}
|
||||
|
||||
ffi::LUA_TTABLE => {
|
||||
@@ -1126,7 +1126,7 @@ impl RawLua {
|
||||
#[cfg(feature = "luau")]
|
||||
if registry.enable_namecall {
|
||||
let map: &mut rustc_hash::FxHashMap<_, crate::types::CallbackPtr> =
|
||||
methods_map.get_or_insert_with(Default::default);
|
||||
methods_map.get_or_insert_default();
|
||||
for (k, m) in ®istry.methods {
|
||||
map.insert(k.as_bytes().to_vec(), &**m);
|
||||
}
|
||||
@@ -1219,13 +1219,11 @@ impl RawLua {
|
||||
Ok(type_id) => Ok(type_id),
|
||||
Err(Error::UserDataTypeMismatch) if ffi::lua_type(state, idx) != ffi::LUA_TUSERDATA => {
|
||||
// Report `FromLuaConversionError` instead
|
||||
// In Luau `luaL_typename` return heap-allocated string that is valid only for
|
||||
// the `state` lifetime.
|
||||
// `lua_typename` is used instead to get a truly static string.
|
||||
let idx_type_name = CStr::from_ptr(ffi::lua_typename(state, ffi::lua_type(state, idx)));
|
||||
let idx_type_name = idx_type_name.to_str().unwrap();
|
||||
let type_name = CStr::from_ptr(ffi::lua_typename(state, ffi::lua_type(state, idx)))
|
||||
.to_str()
|
||||
.unwrap_or("unknown");
|
||||
let message = format!("expected userdata of type '{}'", short_type_name::<T>());
|
||||
Err(Error::from_lua_conversion(idx_type_name, "userdata", message))
|
||||
Err(Error::from_lua_conversion(type_name, "userdata", message))
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
use std::os::raw::c_int;
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
use std::panic::{AssertUnwindSafe, catch_unwind};
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::state::{ExtraData, RawLua};
|
||||
use crate::util::{self, get_internal_metatable, WrappedFailure};
|
||||
use crate::util::{self, WrappedFailure, get_internal_metatable};
|
||||
|
||||
struct StateGuard<'a>(&'a RawLua, *mut ffi::lua_State);
|
||||
|
||||
|
||||
+40
-44
@@ -2,7 +2,6 @@ use std::borrow::{Borrow, Cow};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Deref;
|
||||
use std::os::raw::{c_int, c_void};
|
||||
use std::string::String as StdString;
|
||||
use std::{cmp, fmt, slice, str};
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
@@ -21,23 +20,23 @@ use {
|
||||
///
|
||||
/// Unlike Rust strings, Lua strings may not be valid UTF-8.
|
||||
#[derive(Clone)]
|
||||
pub struct String(pub(crate) ValueRef);
|
||||
pub struct LuaString(pub(crate) ValueRef);
|
||||
|
||||
impl String {
|
||||
impl LuaString {
|
||||
/// Get a [`BorrowedStr`] if the Lua string is valid UTF-8.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use mlua::{Lua, Result, String};
|
||||
/// # use mlua::{Lua, LuaString, Result};
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # let lua = Lua::new();
|
||||
/// let globals = lua.globals();
|
||||
///
|
||||
/// let version: String = globals.get("_VERSION")?;
|
||||
/// let version: LuaString = globals.get("_VERSION")?;
|
||||
/// assert!(version.to_str()?.contains("Lua"));
|
||||
///
|
||||
/// let non_utf8: String = lua.load(r#" "test\255" "#).eval()?;
|
||||
/// let non_utf8: LuaString = lua.load(r#" "test\255" "#).eval()?;
|
||||
/// assert!(non_utf8.to_str().is_err());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
@@ -47,11 +46,11 @@ impl String {
|
||||
BorrowedStr::try_from(self)
|
||||
}
|
||||
|
||||
/// Converts this string to a [`StdString`].
|
||||
/// Converts this Lua string to a [`String`].
|
||||
///
|
||||
/// Any non-Unicode sequences are replaced with [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
|
||||
///
|
||||
/// This method returns [`StdString`] instead of [`Cow<'_, str>`] because lifetime cannot be
|
||||
/// This method returns [`String`] instead of [`Cow<'_, str>`] because lifetime cannot be
|
||||
/// bound to a weak Lua object.
|
||||
///
|
||||
/// [U+FFFD]: std::char::REPLACEMENT_CHARACTER
|
||||
@@ -70,11 +69,11 @@ impl String {
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn to_string_lossy(&self) -> StdString {
|
||||
StdString::from_utf8_lossy(&self.as_bytes()).into_owned()
|
||||
pub fn to_string_lossy(&self) -> String {
|
||||
String::from_utf8_lossy(&self.as_bytes()).into_owned()
|
||||
}
|
||||
|
||||
/// Returns an object that implements [`Display`] for safely printing a Lua [`String`] that may
|
||||
/// Returns an object that implements [`Display`] for safely printing a [`LuaString`] that may
|
||||
/// contain non-Unicode data.
|
||||
///
|
||||
/// This may perform lossy conversion.
|
||||
@@ -92,10 +91,10 @@ impl String {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use mlua::{Lua, Result, String};
|
||||
/// # use mlua::{Lua, LuaString, Result};
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # let lua = Lua::new();
|
||||
/// let non_utf8: String = lua.load(r#" "test\255" "#).eval()?;
|
||||
/// let non_utf8: LuaString = lua.load(r#" "test\255" "#).eval()?;
|
||||
/// assert!(non_utf8.to_str().is_err()); // oh no :(
|
||||
/// assert_eq!(non_utf8.as_bytes(), &b"test\xff"[..]);
|
||||
/// # Ok(())
|
||||
@@ -135,7 +134,7 @@ impl String {
|
||||
(slice, lua)
|
||||
}
|
||||
|
||||
/// Converts this string to a generic C pointer.
|
||||
/// Converts this Lua string to a generic C pointer.
|
||||
///
|
||||
/// There is no way to convert the pointer back to its original value.
|
||||
///
|
||||
@@ -146,7 +145,7 @@ impl String {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for String {
|
||||
impl fmt::Debug for LuaString {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let bytes = self.as_bytes();
|
||||
// Check if the string is valid utf8
|
||||
@@ -162,12 +161,12 @@ impl fmt::Debug for String {
|
||||
|
||||
// Lua strings are basically `&[u8]` slices, so implement `PartialEq` for anything resembling that.
|
||||
//
|
||||
// This makes our `String` comparable with `Vec<u8>`, `[u8]`, `&str` and `String`.
|
||||
// This makes our `LuaString` comparable with `Vec<u8>`, `[u8]`, `&str` and `String`.
|
||||
//
|
||||
// The only downside is that this disallows a comparison with `Cow<str>`, as that only implements
|
||||
// `AsRef<str>`, which collides with this impl. Requiring `AsRef<str>` would fix that, but limit us
|
||||
// in other ways.
|
||||
impl<T> PartialEq<T> for String
|
||||
impl<T> PartialEq<T> for LuaString
|
||||
where
|
||||
T: AsRef<[u8]> + ?Sized,
|
||||
{
|
||||
@@ -176,43 +175,43 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for String {
|
||||
fn eq(&self, other: &String) -> bool {
|
||||
impl PartialEq for LuaString {
|
||||
fn eq(&self, other: &LuaString) -> bool {
|
||||
self.as_bytes() == other.as_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for String {}
|
||||
impl Eq for LuaString {}
|
||||
|
||||
impl<T> PartialOrd<T> for String
|
||||
impl<T> PartialOrd<T> for LuaString
|
||||
where
|
||||
T: AsRef<[u8]> + ?Sized,
|
||||
{
|
||||
fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
|
||||
self.as_bytes().partial_cmp(&other.as_ref())
|
||||
<[u8]>::partial_cmp(&self.as_bytes(), other.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for String {
|
||||
fn partial_cmp(&self, other: &String) -> Option<cmp::Ordering> {
|
||||
impl PartialOrd for LuaString {
|
||||
fn partial_cmp(&self, other: &LuaString) -> Option<cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for String {
|
||||
fn cmp(&self, other: &String) -> cmp::Ordering {
|
||||
impl Ord for LuaString {
|
||||
fn cmp(&self, other: &LuaString) -> cmp::Ordering {
|
||||
self.as_bytes().cmp(&other.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for String {
|
||||
impl Hash for LuaString {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.as_bytes().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl Serialize for String {
|
||||
impl Serialize for LuaString {
|
||||
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
@@ -224,7 +223,7 @@ impl Serialize for String {
|
||||
}
|
||||
}
|
||||
|
||||
struct Display<'a>(&'a String);
|
||||
struct Display<'a>(&'a LuaString);
|
||||
|
||||
impl fmt::Display for Display<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -237,7 +236,7 @@ impl fmt::Display for Display<'_> {
|
||||
pub struct BorrowedStr<'a> {
|
||||
// `buf` points to a readonly memory managed by Lua
|
||||
pub(crate) buf: &'a str,
|
||||
pub(crate) borrow: Cow<'a, String>,
|
||||
pub(crate) borrow: Cow<'a, LuaString>,
|
||||
pub(crate) _lua: Lua,
|
||||
}
|
||||
|
||||
@@ -302,17 +301,14 @@ impl Ord for BorrowedStr<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<&'a String> for BorrowedStr<'a> {
|
||||
impl<'a> TryFrom<&'a LuaString> for BorrowedStr<'a> {
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn try_from(value: &'a String) -> Result<Self> {
|
||||
fn try_from(value: &'a LuaString) -> Result<Self> {
|
||||
let BorrowedBytes { buf, borrow, _lua } = BorrowedBytes::from(value);
|
||||
let buf = str::from_utf8(buf).map_err(|e| Error::FromLuaConversionError {
|
||||
from: "string",
|
||||
to: "&str".to_string(),
|
||||
message: Some(e.to_string()),
|
||||
})?;
|
||||
let buf =
|
||||
str::from_utf8(buf).map_err(|e| Error::from_lua_conversion("string", "&str", e.to_string()))?;
|
||||
Ok(Self { buf, borrow, _lua })
|
||||
}
|
||||
}
|
||||
@@ -321,7 +317,7 @@ impl<'a> TryFrom<&'a String> for BorrowedStr<'a> {
|
||||
pub struct BorrowedBytes<'a> {
|
||||
// `buf` points to a readonly memory managed by Lua
|
||||
pub(crate) buf: &'a [u8],
|
||||
pub(crate) borrow: Cow<'a, String>,
|
||||
pub(crate) borrow: Cow<'a, LuaString>,
|
||||
pub(crate) _lua: Lua,
|
||||
}
|
||||
|
||||
@@ -389,9 +385,9 @@ impl<'a> IntoIterator for &'a BorrowedBytes<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a String> for BorrowedBytes<'a> {
|
||||
impl<'a> From<&'a LuaString> for BorrowedBytes<'a> {
|
||||
#[inline]
|
||||
fn from(value: &'a String) -> Self {
|
||||
fn from(value: &'a LuaString) -> Self {
|
||||
let (buf, _lua) = unsafe { value.to_slice() };
|
||||
let borrow = Cow::Borrowed(value);
|
||||
Self { buf, borrow, _lua }
|
||||
@@ -400,7 +396,7 @@ impl<'a> From<&'a String> for BorrowedBytes<'a> {
|
||||
|
||||
struct WrappedString<T: AsRef<[u8]>>(T);
|
||||
|
||||
impl String {
|
||||
impl LuaString {
|
||||
/// Wraps bytes, returning an opaque type that implements [`IntoLua`] trait.
|
||||
///
|
||||
/// This function uses [`Lua::create_string`] under the hood.
|
||||
@@ -415,7 +411,7 @@ impl<T: AsRef<[u8]>> IntoLua for WrappedString<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl LuaType for String {
|
||||
impl LuaType for LuaString {
|
||||
const TYPE_ID: c_int = ffi::LUA_TSTRING;
|
||||
}
|
||||
|
||||
@@ -424,9 +420,9 @@ mod assertions {
|
||||
use super::*;
|
||||
|
||||
#[cfg(not(feature = "send"))]
|
||||
static_assertions::assert_not_impl_any!(String: Send);
|
||||
static_assertions::assert_not_impl_any!(LuaString: Send);
|
||||
#[cfg(feature = "send")]
|
||||
static_assertions::assert_impl_all!(String: Send, Sync);
|
||||
static_assertions::assert_impl_all!(LuaString: Send, Sync);
|
||||
#[cfg(feature = "send")]
|
||||
static_assertions::assert_impl_all!(BorrowedBytes: Send, Sync);
|
||||
#[cfg(feature = "send")]
|
||||
|
||||
+172
-14
@@ -1,15 +1,173 @@
|
||||
//! Lua table handling.
|
||||
//!
|
||||
//! Tables are Lua's primary data structure, used for arrays, dictionaries, objects, modules,
|
||||
//! and more. This module provides types for creating and manipulating Lua tables from Rust.
|
||||
//!
|
||||
//! # Main Types
|
||||
//!
|
||||
//! - [`Table`] - A handle to a Lua table.
|
||||
//! - [`TablePairs`] - An iterator over key-value pairs in a table.
|
||||
//! - [`TableSequence`] - An iterator over the array (sequence) portion of a table.
|
||||
//!
|
||||
//! # Basic Operations
|
||||
//!
|
||||
//! Tables support key-value access similar to Rust's `HashMap`:
|
||||
//!
|
||||
//! ```
|
||||
//! # use mlua::{Lua, Result};
|
||||
//! # fn main() -> Result<()> {
|
||||
//! let lua = Lua::new();
|
||||
//! let table = lua.create_table()?;
|
||||
//!
|
||||
//! // Set and get values
|
||||
//! table.set("key", "value")?;
|
||||
//! let value: String = table.get("key")?;
|
||||
//! assert_eq!(value, "value");
|
||||
//!
|
||||
//! // Keys and values can be any Lua-compatible type
|
||||
//! table.set(1, "first")?;
|
||||
//! table.set("nested", lua.create_table()?)?;
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! # Array Operations
|
||||
//!
|
||||
//! Tables can be used as arrays with 1-based indexing:
|
||||
//!
|
||||
//! ```
|
||||
//! # use mlua::{Lua, Result};
|
||||
//! # fn main() -> Result<()> {
|
||||
//! let lua = Lua::new();
|
||||
//! let array = lua.create_table()?;
|
||||
//!
|
||||
//! // Push values to the end (like Vec::push)
|
||||
//! array.push("first")?;
|
||||
//! array.push("second")?;
|
||||
//! array.push("third")?;
|
||||
//!
|
||||
//! // Pop from the end
|
||||
//! let last: String = array.pop()?;
|
||||
//! assert_eq!(last, "third");
|
||||
//!
|
||||
//! // Get length
|
||||
//! assert_eq!(array.raw_len(), 2);
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! # Iteration
|
||||
//!
|
||||
//! Iterate over all key-value pairs with [`Table::pairs`]:
|
||||
//!
|
||||
//! ```
|
||||
//! # use mlua::{Lua, Result, Value};
|
||||
//! # fn main() -> Result<()> {
|
||||
//! let lua = Lua::new();
|
||||
//! let table = lua.create_table()?;
|
||||
//! table.set("a", 1)?;
|
||||
//! table.set("b", 2)?;
|
||||
//!
|
||||
//! for pair in table.pairs::<String, i32>() {
|
||||
//! let (key, value) = pair?;
|
||||
//! println!("{key} = {value}");
|
||||
//! }
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! For array portions, use [`Table::sequence_values`]:
|
||||
//!
|
||||
//! ```
|
||||
//! # use mlua::{Lua, Result};
|
||||
//! # fn main() -> Result<()> {
|
||||
//! let lua = Lua::new();
|
||||
//! let array = lua.create_sequence_from(["a", "b", "c"])?;
|
||||
//!
|
||||
//! for value in array.sequence_values::<String>() {
|
||||
//! println!("{}", value?);
|
||||
//! }
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! # Raw vs Normal Access
|
||||
//!
|
||||
//! Methods prefixed with `raw_` (like [`Table::raw_get`], [`Table::raw_set`]) bypass
|
||||
//! metamethods, directly accessing the table's contents. Normal methods may trigger
|
||||
//! `__index`, `__newindex`, and other metamethods:
|
||||
//!
|
||||
//! ```
|
||||
//! # use mlua::{Lua, Result};
|
||||
//! # fn main() -> Result<()> {
|
||||
//! let lua = Lua::new();
|
||||
//!
|
||||
//! // raw_set bypasses __newindex metamethod
|
||||
//! let t = lua.create_table()?;
|
||||
//! t.raw_set("key", "value")?;
|
||||
//!
|
||||
//! // raw_get bypasses __index metamethod
|
||||
//! let v: String = t.raw_get("key")?;
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! # Metatables
|
||||
//!
|
||||
//! Tables can have metatables that customize their behavior:
|
||||
//!
|
||||
//! ```
|
||||
//! # use mlua::{Lua, Result};
|
||||
//! # fn main() -> Result<()> {
|
||||
//! let lua = Lua::new();
|
||||
//!
|
||||
//! let table = lua.create_table()?;
|
||||
//! let metatable = lua.create_table()?;
|
||||
//!
|
||||
//! // Set a default value via __index
|
||||
//! metatable.set("__index", lua.create_function(|_, _: ()| Ok("default"))?)?;
|
||||
//! table.set_metatable(Some(metatable))?;
|
||||
//!
|
||||
//! // Accessing missing keys returns "default"
|
||||
//! let value: String = table.get("missing")?;
|
||||
//! assert_eq!(value, "default");
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! # Global Table
|
||||
//!
|
||||
//! The Lua global environment is itself a table, accessible via [`Lua::globals`]:
|
||||
//!
|
||||
//! ```
|
||||
//! # use mlua::{Lua, Result};
|
||||
//! # fn main() -> Result<()> {
|
||||
//! let lua = Lua::new();
|
||||
//! let globals = lua.globals();
|
||||
//!
|
||||
//! // Set a global variable
|
||||
//! globals.set("my_var", 42)?;
|
||||
//!
|
||||
//! // Now accessible from Lua code
|
||||
//! let result: i32 = lua.load("my_var + 8").eval()?;
|
||||
//! assert_eq!(result, 50);
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! [`Lua::globals`]: crate::Lua::globals
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::os::raw::c_void;
|
||||
use std::string::String as StdString;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::function::Function;
|
||||
use crate::state::{LuaGuard, RawLua, WeakLua};
|
||||
use crate::traits::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, ObjectLike};
|
||||
use crate::types::{Integer, ValueRef};
|
||||
use crate::util::{assert_stack, check_stack, get_metatable_ptr, StackGuard};
|
||||
use crate::util::{StackGuard, assert_stack, check_stack, get_metatable_ptr};
|
||||
use crate::value::{Nil, Value};
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
@@ -226,15 +384,15 @@ impl Table {
|
||||
// Compare using `__eq` metamethod if exists
|
||||
// First, check the self for the metamethod.
|
||||
// If self does not define it, then check the other table.
|
||||
if let Some(mt) = self.metatable() {
|
||||
if mt.contains_key("__eq")? {
|
||||
return mt.get::<Function>("__eq")?.call((self, other));
|
||||
}
|
||||
if let Some(mt) = self.metatable()
|
||||
&& let Some(eq_func) = mt.get::<Option<Function>>("__eq")?
|
||||
{
|
||||
return eq_func.call((self, other));
|
||||
}
|
||||
if let Some(mt) = other.metatable() {
|
||||
if mt.contains_key("__eq")? {
|
||||
return mt.get::<Function>("__eq")?.call((self, other));
|
||||
}
|
||||
if let Some(mt) = other.metatable()
|
||||
&& let Some(eq_func) = mt.get::<Option<Function>>("__eq")?
|
||||
{
|
||||
return eq_func.call((self, other));
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
@@ -1008,7 +1166,7 @@ impl ObjectLike for Table {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_string(&self) -> Result<StdString> {
|
||||
fn to_string(&self) -> Result<String> {
|
||||
Value::Table(Table(self.0.clone())).to_string()
|
||||
}
|
||||
|
||||
@@ -1070,7 +1228,7 @@ impl Serialize for SerializableTable<'_> {
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
use crate::serde::de::{check_value_for_skip, MapPairs, RecursionGuard};
|
||||
use crate::serde::de::{MapPairs, RecursionGuard, check_value_for_skip};
|
||||
use crate::value::SerializableValue;
|
||||
|
||||
let convert_result = |res: Result<()>, serialize_err: Option<S::Error>| match res {
|
||||
@@ -1098,7 +1256,7 @@ impl Serialize for SerializableTable<'_> {
|
||||
seq.serialize_element(&SerializableValue::new(&value, options, Some(visited)))
|
||||
.map_err(|err| {
|
||||
serialize_err = Some(err);
|
||||
Error::SerializeError(StdString::new())
|
||||
Error::SerializeError(String::new())
|
||||
})
|
||||
});
|
||||
convert_result(res, serialize_err)?;
|
||||
@@ -1123,7 +1281,7 @@ impl Serialize for SerializableTable<'_> {
|
||||
)
|
||||
.map_err(|err| {
|
||||
serialize_err = Some(err);
|
||||
Error::SerializeError(StdString::new())
|
||||
Error::SerializeError(String::new())
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
+2
-1
@@ -6,7 +6,7 @@ use crate::function::Function;
|
||||
use crate::state::RawLua;
|
||||
use crate::traits::{FromLuaMulti, IntoLuaMulti};
|
||||
use crate::types::{LuaType, ValueRef};
|
||||
use crate::util::{check_stack, error_traceback_thread, pop_error, StackGuard};
|
||||
use crate::util::{StackGuard, check_stack, error_traceback_thread, pop_error};
|
||||
|
||||
#[cfg(not(feature = "luau"))]
|
||||
use crate::{
|
||||
@@ -523,6 +523,7 @@ impl<R> AsyncThread<R> {
|
||||
#[cfg(feature = "async")]
|
||||
impl<R> Drop for AsyncThread<R> {
|
||||
fn drop(&mut self) {
|
||||
#[allow(clippy::collapsible_if)]
|
||||
if self.recycle {
|
||||
if let Some(lua) = self.thread.0.lua.try_lock() {
|
||||
unsafe {
|
||||
|
||||
+2
-3
@@ -1,5 +1,4 @@
|
||||
use std::os::raw::c_int;
|
||||
use std::string::String as StdString;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
@@ -236,7 +235,7 @@ pub trait ObjectLike: Sealed {
|
||||
/// Converts the object to a string in a human-readable format.
|
||||
///
|
||||
/// This might invoke the `__tostring` metamethod.
|
||||
fn to_string(&self) -> Result<StdString>;
|
||||
fn to_string(&self) -> Result<String>;
|
||||
|
||||
/// Converts the object to a Lua value.
|
||||
fn to_value(&self) -> Value;
|
||||
@@ -339,7 +338,7 @@ impl_lua_native_fn!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
|
||||
|
||||
pub(crate) trait ShortTypeName {
|
||||
#[inline(always)]
|
||||
fn type_name() -> StdString {
|
||||
fn type_name() -> String {
|
||||
short_type_name::<Self>()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ mod inner {
|
||||
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0 .0
|
||||
&self.0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,10 +55,10 @@ impl Drop for ValueRef {
|
||||
if let Some(ValueRefIndex(index)) = self.index_count.take() {
|
||||
// It's guaranteed that the inner value returns exactly once.
|
||||
// This means in particular that the value is not dropped.
|
||||
if XRc::into_inner(index).is_some() {
|
||||
if let Some(lua) = self.lua.try_lock() {
|
||||
unsafe { lua.drop_ref(self) };
|
||||
}
|
||||
if XRc::into_inner(index).is_some()
|
||||
&& let Some(lua) = self.lua.try_lock()
|
||||
{
|
||||
unsafe { lua.drop_ref(self) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
-34
@@ -3,16 +3,15 @@ use std::ffi::CStr;
|
||||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use std::string::String as StdString;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::function::Function;
|
||||
use crate::state::Lua;
|
||||
use crate::string::String;
|
||||
use crate::string::LuaString;
|
||||
use crate::table::{Table, TablePairs};
|
||||
use crate::traits::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti};
|
||||
use crate::types::{MaybeSend, ValueRef};
|
||||
use crate::util::{check_stack, get_userdata, push_string, short_type_name, take_userdata, StackGuard};
|
||||
use crate::util::{StackGuard, check_stack, get_userdata, push_string, short_type_name, take_userdata};
|
||||
use crate::value::Value;
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
@@ -30,8 +29,8 @@ pub use r#ref::{UserDataRef, UserDataRefMut};
|
||||
pub use registry::UserDataRegistry;
|
||||
pub(crate) use registry::{RawUserDataRegistry, UserDataProxy};
|
||||
pub(crate) use util::{
|
||||
borrow_userdata_scoped, borrow_userdata_scoped_mut, collect_userdata, init_userdata_metatable,
|
||||
TypeIdHints,
|
||||
TypeIdHints, borrow_userdata_scoped, borrow_userdata_scoped_mut, collect_userdata,
|
||||
init_userdata_metatable,
|
||||
};
|
||||
|
||||
/// Kinds of metamethods that can be overridden.
|
||||
@@ -185,7 +184,7 @@ impl PartialEq<MetaMethod> for &str {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<MetaMethod> for StdString {
|
||||
impl PartialEq<MetaMethod> for String {
|
||||
fn eq(&self, other: &MetaMethod) -> bool {
|
||||
self == other.name()
|
||||
}
|
||||
@@ -279,7 +278,7 @@ impl AsRef<str> for MetaMethod {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MetaMethod> for StdString {
|
||||
impl From<MetaMethod> for String {
|
||||
#[inline]
|
||||
fn from(method: MetaMethod) -> Self {
|
||||
method.name().to_owned()
|
||||
@@ -295,7 +294,7 @@ pub trait UserDataMethods<T> {
|
||||
///
|
||||
/// If `add_meta_method` is used to set the `__index` metamethod, the `__index` metamethod will
|
||||
/// be used as a fall-back if no regular method is found.
|
||||
fn add_method<M, A, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_method<M, A, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: Fn(&Lua, &T, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -306,7 +305,7 @@ pub trait UserDataMethods<T> {
|
||||
/// Refer to [`add_method`] for more information about the implementation.
|
||||
///
|
||||
/// [`add_method`]: UserDataMethods::add_method
|
||||
fn add_method_mut<M, A, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_method_mut<M, A, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: FnMut(&Lua, &mut T, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -320,7 +319,7 @@ pub trait UserDataMethods<T> {
|
||||
/// The method can be called only once per userdata instance, subsequent calls will result in a
|
||||
/// [`Error::UserDataDestructed`] error.
|
||||
#[doc(hidden)]
|
||||
fn add_method_once<M, A, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_method_once<M, A, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
T: 'static,
|
||||
M: Fn(&Lua, T, A) -> Result<R> + MaybeSend + 'static,
|
||||
@@ -342,7 +341,7 @@ pub trait UserDataMethods<T> {
|
||||
/// [`add_method`]: UserDataMethods::add_method
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
fn add_async_method<M, A, MR, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_async_method<M, A, MR, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
T: 'static,
|
||||
M: Fn(Lua, UserDataRef<T>, A) -> MR + MaybeSend + 'static,
|
||||
@@ -357,7 +356,7 @@ pub trait UserDataMethods<T> {
|
||||
/// [`add_method`]: UserDataMethods::add_method
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
fn add_async_method_mut<M, A, MR, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_async_method_mut<M, A, MR, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
T: 'static,
|
||||
M: Fn(Lua, UserDataRefMut<T>, A) -> MR + MaybeSend + 'static,
|
||||
@@ -375,7 +374,7 @@ pub trait UserDataMethods<T> {
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
#[doc(hidden)]
|
||||
fn add_async_method_once<M, A, MR, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_async_method_once<M, A, MR, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
T: 'static,
|
||||
M: Fn(Lua, T, A) -> MR + MaybeSend + 'static,
|
||||
@@ -398,7 +397,7 @@ pub trait UserDataMethods<T> {
|
||||
/// The first argument will be a [`AnyUserData`] of type `T` if the method is called with Lua
|
||||
/// method syntax: `my_userdata:my_method(arg1, arg2)`, or it is passed in as the first
|
||||
/// argument: `my_userdata.my_method(my_userdata, arg1, arg2)`.
|
||||
fn add_function<F, A, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_function<F, A, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: Fn(&Lua, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -409,7 +408,7 @@ pub trait UserDataMethods<T> {
|
||||
/// This is a version of [`add_function`] that accepts a `FnMut` argument.
|
||||
///
|
||||
/// [`add_function`]: UserDataMethods::add_function
|
||||
fn add_function_mut<F, A, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_function_mut<F, A, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: FnMut(&Lua, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -423,7 +422,7 @@ pub trait UserDataMethods<T> {
|
||||
/// [`add_function`]: UserDataMethods::add_function
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
fn add_async_function<F, A, FR, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_async_function<F, A, FR, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: Fn(Lua, A) -> FR + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -438,7 +437,7 @@ pub trait UserDataMethods<T> {
|
||||
/// side has a metatable. To prevent this, use [`add_meta_function`].
|
||||
///
|
||||
/// [`add_meta_function`]: UserDataMethods::add_meta_function
|
||||
fn add_meta_method<M, A, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_meta_method<M, A, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: Fn(&Lua, &T, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -452,7 +451,7 @@ pub trait UserDataMethods<T> {
|
||||
/// side has a metatable. To prevent this, use [`add_meta_function`].
|
||||
///
|
||||
/// [`add_meta_function`]: UserDataMethods::add_meta_function
|
||||
fn add_meta_method_mut<M, A, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_meta_method_mut<M, A, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: FnMut(&Lua, &mut T, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -468,7 +467,7 @@ pub trait UserDataMethods<T> {
|
||||
docsrs,
|
||||
doc(cfg(all(feature = "async", not(any(feature = "lua51", feature = "luau")))))
|
||||
)]
|
||||
fn add_async_meta_method<M, A, MR, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_async_meta_method<M, A, MR, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
T: 'static,
|
||||
M: Fn(Lua, UserDataRef<T>, A) -> MR + MaybeSend + 'static,
|
||||
@@ -484,7 +483,7 @@ pub trait UserDataMethods<T> {
|
||||
/// [`add_meta_method_mut`]: UserDataMethods::add_meta_method_mut
|
||||
#[cfg(all(feature = "async", not(any(feature = "lua51", feature = "luau"))))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
fn add_async_meta_method_mut<M, A, MR, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_async_meta_method_mut<M, A, MR, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
T: 'static,
|
||||
M: Fn(Lua, UserDataRefMut<T>, A) -> MR + MaybeSend + 'static,
|
||||
@@ -497,7 +496,7 @@ pub trait UserDataMethods<T> {
|
||||
/// Metamethods for binary operators can be triggered if either the left or right argument to
|
||||
/// the binary operator has a metatable, so the first argument here is not necessarily a
|
||||
/// userdata of type `T`.
|
||||
fn add_meta_function<F, A, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_meta_function<F, A, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: Fn(&Lua, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -508,7 +507,7 @@ pub trait UserDataMethods<T> {
|
||||
/// This is a version of [`add_meta_function`] that accepts a `FnMut` argument.
|
||||
///
|
||||
/// [`add_meta_function`]: UserDataMethods::add_meta_function
|
||||
fn add_meta_function_mut<F, A, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_meta_function_mut<F, A, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: FnMut(&Lua, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -524,7 +523,7 @@ pub trait UserDataMethods<T> {
|
||||
docsrs,
|
||||
doc(cfg(all(feature = "async", not(any(feature = "lua51", feature = "luau")))))
|
||||
)]
|
||||
fn add_async_meta_function<F, A, FR, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_async_meta_function<F, A, FR, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: Fn(Lua, A) -> FR + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -543,7 +542,7 @@ pub trait UserDataFields<T> {
|
||||
///
|
||||
/// If `add_meta_method` is used to set the `__index` metamethod, it will
|
||||
/// be used as a fall-back if no regular field or method are found.
|
||||
fn add_field<V>(&mut self, name: impl Into<StdString>, value: V)
|
||||
fn add_field<V>(&mut self, name: impl Into<String>, value: V)
|
||||
where
|
||||
V: IntoLua + 'static;
|
||||
|
||||
@@ -554,7 +553,7 @@ pub trait UserDataFields<T> {
|
||||
///
|
||||
/// If `add_meta_method` is used to set the `__index` metamethod, the `__index` metamethod will
|
||||
/// be used as a fall-back if no regular field or method are found.
|
||||
fn add_field_method_get<M, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_field_method_get<M, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: Fn(&Lua, &T) -> Result<R> + MaybeSend + 'static,
|
||||
R: IntoLua;
|
||||
@@ -567,21 +566,21 @@ pub trait UserDataFields<T> {
|
||||
///
|
||||
/// If `add_meta_method` is used to set the `__newindex` metamethod, the `__newindex` metamethod
|
||||
/// will be used as a fall-back if no regular field is found.
|
||||
fn add_field_method_set<M, A>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_field_method_set<M, A>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: FnMut(&Lua, &mut T, A) -> Result<()> + MaybeSend + 'static,
|
||||
A: FromLua;
|
||||
|
||||
/// Add a regular field getter as a function which accepts a generic [`AnyUserData`] of type `T`
|
||||
/// argument.
|
||||
fn add_field_function_get<F, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_field_function_get<F, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: Fn(&Lua, AnyUserData) -> Result<R> + MaybeSend + 'static,
|
||||
R: IntoLua;
|
||||
|
||||
/// Add a regular field setter as a function which accepts a generic [`AnyUserData`] of type `T`
|
||||
/// first argument.
|
||||
fn add_field_function_set<F, A>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_field_function_set<F, A>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: FnMut(&Lua, AnyUserData, A) -> Result<()> + MaybeSend + 'static,
|
||||
A: FromLua;
|
||||
@@ -594,7 +593,7 @@ pub trait UserDataFields<T> {
|
||||
///
|
||||
/// `mlua` will trigger an error on an attempt to define a protected metamethod,
|
||||
/// like `__gc` or `__metatable`.
|
||||
fn add_meta_field<V>(&mut self, name: impl Into<StdString>, value: V)
|
||||
fn add_meta_field<V>(&mut self, name: impl Into<String>, value: V)
|
||||
where
|
||||
V: IntoLua + 'static;
|
||||
|
||||
@@ -606,7 +605,7 @@ pub trait UserDataFields<T> {
|
||||
///
|
||||
/// `mlua` will trigger an error on an attempt to define a protected metamethod,
|
||||
/// like `__gc` or `__metatable`.
|
||||
fn add_meta_field_with<F, R>(&mut self, name: impl Into<StdString>, f: F)
|
||||
fn add_meta_field_with<F, R>(&mut self, name: impl Into<String>, f: F)
|
||||
where
|
||||
F: FnOnce(&Lua) -> Result<R> + 'static,
|
||||
R: IntoLua;
|
||||
@@ -1022,7 +1021,7 @@ impl AnyUserData {
|
||||
/// Returns a type name of this userdata (from a metatable field).
|
||||
///
|
||||
/// If no type name is set, returns `None`.
|
||||
pub fn type_name(&self) -> Result<Option<StdString>> {
|
||||
pub fn type_name(&self) -> Result<Option<String>> {
|
||||
let lua = self.0.lua.lock();
|
||||
let state = lua.state();
|
||||
unsafe {
|
||||
@@ -1039,7 +1038,7 @@ impl AnyUserData {
|
||||
ffi::luaL_getmetafield(state, -1, MetaMethod::Type.as_cstr().as_ptr())
|
||||
};
|
||||
match name_type {
|
||||
ffi::LUA_TSTRING => Ok(Some(String(lua.pop_ref()).to_str()?.to_owned())),
|
||||
ffi::LUA_TSTRING => Ok(Some(LuaString(lua.pop_ref()).to_str()?.to_owned())),
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
@@ -1126,13 +1125,13 @@ impl UserDataMetatable {
|
||||
/// It skips restricted metamethods, such as `__gc` or `__metatable`.
|
||||
///
|
||||
/// This struct is created by the [`UserDataMetatable::pairs`] method.
|
||||
pub struct UserDataMetatablePairs<'a, V>(TablePairs<'a, StdString, V>);
|
||||
pub struct UserDataMetatablePairs<'a, V>(TablePairs<'a, String, V>);
|
||||
|
||||
impl<V> Iterator for UserDataMetatablePairs<'_, V>
|
||||
where
|
||||
V: FromLua,
|
||||
{
|
||||
type Item = Result<(StdString, V)>;
|
||||
type Item = Result<(String, V)>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
|
||||
@@ -173,10 +173,10 @@ pub(crate) enum ScopedUserDataVariant<T> {
|
||||
impl<T> Drop for ScopedUserDataVariant<T> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
if let Self::Boxed(value) = self {
|
||||
if let Ok(value) = value.try_borrow_mut() {
|
||||
unsafe { drop(Box::from_raw(*value)) };
|
||||
}
|
||||
if let Self::Boxed(value) = self
|
||||
&& let Ok(value) = value.try_borrow_mut()
|
||||
{
|
||||
unsafe { drop(Box::from_raw(*value)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
use std::string::String as StdString;
|
||||
|
||||
use crate::Function;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::state::WeakLua;
|
||||
use crate::table::Table;
|
||||
use crate::traits::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, ObjectLike};
|
||||
use crate::userdata::AnyUserData;
|
||||
use crate::value::Value;
|
||||
use crate::Function;
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
use crate::function::AsyncCallFuture;
|
||||
@@ -88,7 +86,7 @@ impl ObjectLike for AnyUserData {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_string(&self) -> Result<StdString> {
|
||||
fn to_string(&self) -> Result<String> {
|
||||
Value::UserData(self.clone()).to_string()
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
use std::any::{type_name, TypeId};
|
||||
use std::any::{TypeId, type_name};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::os::raw::c_int;
|
||||
use std::{fmt, mem};
|
||||
@@ -446,11 +446,11 @@ impl<T> DerefMut for UserDataRefMutInner<T> {
|
||||
fn try_value_to_userdata<T>(value: Value) -> Result<AnyUserData> {
|
||||
match value {
|
||||
Value::UserData(ud) => Ok(ud),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "userdata".to_string(),
|
||||
message: Some(format!("expected userdata of type {}", type_name::<T>())),
|
||||
}),
|
||||
_ => Err(Error::from_lua_conversion(
|
||||
value.type_name(),
|
||||
"userdata",
|
||||
format!("expected userdata of type {}", type_name::<T>()),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
-27
@@ -4,15 +4,14 @@ use std::any::TypeId;
|
||||
use std::cell::RefCell;
|
||||
use std::marker::PhantomData;
|
||||
use std::os::raw::c_void;
|
||||
use std::string::String as StdString;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::state::{Lua, LuaGuard};
|
||||
use crate::traits::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti};
|
||||
use crate::types::{Callback, MaybeSend};
|
||||
use crate::userdata::{
|
||||
borrow_userdata_scoped, borrow_userdata_scoped_mut, AnyUserData, MetaMethod, TypeIdHints, UserData,
|
||||
UserDataFields, UserDataMethods, UserDataStorage,
|
||||
AnyUserData, MetaMethod, TypeIdHints, UserData, UserDataFields, UserDataMethods, UserDataStorage,
|
||||
borrow_userdata_scoped, borrow_userdata_scoped_mut,
|
||||
};
|
||||
use crate::util::short_type_name;
|
||||
use crate::value::Value;
|
||||
@@ -55,7 +54,7 @@ pub(crate) struct RawUserDataRegistry {
|
||||
|
||||
pub(crate) destructor: ffi::lua_CFunction,
|
||||
pub(crate) type_id: Option<TypeId>,
|
||||
pub(crate) type_name: StdString,
|
||||
pub(crate) type_name: String,
|
||||
|
||||
#[cfg(feature = "luau")]
|
||||
pub(crate) enable_namecall: bool,
|
||||
@@ -368,7 +367,7 @@ impl<T> UserDataRegistry<T> {
|
||||
method: name.to_string(),
|
||||
type_name: value.type_name(),
|
||||
message: Some("expected nil, table or function".to_string()),
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -382,12 +381,12 @@ impl<T> UserDataRegistry<T> {
|
||||
}
|
||||
|
||||
// Returns function name for the type `T`, without the module path
|
||||
fn get_function_name<T>(name: &str) -> StdString {
|
||||
fn get_function_name<T>(name: &str) -> String {
|
||||
format!("{}.{name}", short_type_name::<T>())
|
||||
}
|
||||
|
||||
impl<T> UserDataFields<T> for UserDataRegistry<T> {
|
||||
fn add_field<V>(&mut self, name: impl Into<StdString>, value: V)
|
||||
fn add_field<V>(&mut self, name: impl Into<String>, value: V)
|
||||
where
|
||||
V: IntoLua + 'static,
|
||||
{
|
||||
@@ -395,7 +394,7 @@ impl<T> UserDataFields<T> for UserDataRegistry<T> {
|
||||
self.raw.fields.push((name, value.into_lua(self.lua.lua())));
|
||||
}
|
||||
|
||||
fn add_field_method_get<M, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_field_method_get<M, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: Fn(&Lua, &T) -> Result<R> + MaybeSend + 'static,
|
||||
R: IntoLua,
|
||||
@@ -405,7 +404,7 @@ impl<T> UserDataFields<T> for UserDataRegistry<T> {
|
||||
self.raw.field_getters.push((name, callback));
|
||||
}
|
||||
|
||||
fn add_field_method_set<M, A>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_field_method_set<M, A>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: FnMut(&Lua, &mut T, A) -> Result<()> + MaybeSend + 'static,
|
||||
A: FromLua,
|
||||
@@ -415,7 +414,7 @@ impl<T> UserDataFields<T> for UserDataRegistry<T> {
|
||||
self.raw.field_setters.push((name, callback));
|
||||
}
|
||||
|
||||
fn add_field_function_get<F, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_field_function_get<F, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: Fn(&Lua, AnyUserData) -> Result<R> + MaybeSend + 'static,
|
||||
R: IntoLua,
|
||||
@@ -425,7 +424,7 @@ impl<T> UserDataFields<T> for UserDataRegistry<T> {
|
||||
self.raw.field_getters.push((name, callback));
|
||||
}
|
||||
|
||||
fn add_field_function_set<F, A>(&mut self, name: impl Into<StdString>, mut function: F)
|
||||
fn add_field_function_set<F, A>(&mut self, name: impl Into<String>, mut function: F)
|
||||
where
|
||||
F: FnMut(&Lua, AnyUserData, A) -> Result<()> + MaybeSend + 'static,
|
||||
A: FromLua,
|
||||
@@ -435,7 +434,7 @@ impl<T> UserDataFields<T> for UserDataRegistry<T> {
|
||||
self.raw.field_setters.push((name, callback));
|
||||
}
|
||||
|
||||
fn add_meta_field<V>(&mut self, name: impl Into<StdString>, value: V)
|
||||
fn add_meta_field<V>(&mut self, name: impl Into<String>, value: V)
|
||||
where
|
||||
V: IntoLua + 'static,
|
||||
{
|
||||
@@ -445,7 +444,7 @@ impl<T> UserDataFields<T> for UserDataRegistry<T> {
|
||||
self.raw.meta_fields.push((name, field));
|
||||
}
|
||||
|
||||
fn add_meta_field_with<F, R>(&mut self, name: impl Into<StdString>, f: F)
|
||||
fn add_meta_field_with<F, R>(&mut self, name: impl Into<String>, f: F)
|
||||
where
|
||||
F: FnOnce(&Lua) -> Result<R> + 'static,
|
||||
R: IntoLua,
|
||||
@@ -458,7 +457,7 @@ impl<T> UserDataFields<T> for UserDataRegistry<T> {
|
||||
}
|
||||
|
||||
impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
fn add_method<M, A, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_method<M, A, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: Fn(&Lua, &T, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -469,7 +468,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
self.raw.methods.push((name, callback));
|
||||
}
|
||||
|
||||
fn add_method_mut<M, A, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_method_mut<M, A, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: FnMut(&Lua, &mut T, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -481,7 +480,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
fn add_async_method<M, A, MR, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_async_method<M, A, MR, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
T: 'static,
|
||||
M: Fn(Lua, UserDataRef<T>, A) -> MR + MaybeSend + 'static,
|
||||
@@ -495,7 +494,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
fn add_async_method_mut<M, A, MR, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_async_method_mut<M, A, MR, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
T: 'static,
|
||||
M: Fn(Lua, UserDataRefMut<T>, A) -> MR + MaybeSend + 'static,
|
||||
@@ -508,7 +507,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
self.raw.async_methods.push((name, callback));
|
||||
}
|
||||
|
||||
fn add_function<F, A, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_function<F, A, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: Fn(&Lua, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -519,7 +518,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
self.raw.methods.push((name, callback));
|
||||
}
|
||||
|
||||
fn add_function_mut<F, A, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_function_mut<F, A, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: FnMut(&Lua, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -531,7 +530,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
fn add_async_function<F, A, FR, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_async_function<F, A, FR, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: Fn(Lua, A) -> FR + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -543,7 +542,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
self.raw.async_methods.push((name, callback));
|
||||
}
|
||||
|
||||
fn add_meta_method<M, A, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_meta_method<M, A, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: Fn(&Lua, &T, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -554,7 +553,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
self.raw.meta_methods.push((name, callback));
|
||||
}
|
||||
|
||||
fn add_meta_method_mut<M, A, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_meta_method_mut<M, A, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
M: FnMut(&Lua, &mut T, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -566,7 +565,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "async", not(any(feature = "lua51", feature = "luau"))))]
|
||||
fn add_async_meta_method<M, A, MR, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_async_meta_method<M, A, MR, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
T: 'static,
|
||||
M: Fn(Lua, UserDataRef<T>, A) -> MR + MaybeSend + 'static,
|
||||
@@ -580,7 +579,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "async", not(any(feature = "lua51", feature = "luau"))))]
|
||||
fn add_async_meta_method_mut<M, A, MR, R>(&mut self, name: impl Into<StdString>, method: M)
|
||||
fn add_async_meta_method_mut<M, A, MR, R>(&mut self, name: impl Into<String>, method: M)
|
||||
where
|
||||
T: 'static,
|
||||
M: Fn(Lua, UserDataRefMut<T>, A) -> MR + MaybeSend + 'static,
|
||||
@@ -593,7 +592,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
self.raw.async_meta_methods.push((name, callback));
|
||||
}
|
||||
|
||||
fn add_meta_function<F, A, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_meta_function<F, A, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: Fn(&Lua, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -604,7 +603,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
self.raw.meta_methods.push((name, callback));
|
||||
}
|
||||
|
||||
fn add_meta_function_mut<F, A, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_meta_function_mut<F, A, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: FnMut(&Lua, A) -> Result<R> + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
@@ -616,7 +615,7 @@ impl<T> UserDataMethods<T> for UserDataRegistry<T> {
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "async", not(any(feature = "lua51", feature = "luau"))))]
|
||||
fn add_async_meta_function<F, A, FR, R>(&mut self, name: impl Into<StdString>, function: F)
|
||||
fn add_async_meta_function<F, A, FR, R>(&mut self, name: impl Into<String>, function: F)
|
||||
where
|
||||
F: Fn(Lua, A) -> FR + MaybeSend + 'static,
|
||||
A: FromLuaMulti,
|
||||
|
||||
+3
-3
@@ -2,15 +2,15 @@ use std::any::Any;
|
||||
use std::fmt::Write as _;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::os::raw::{c_int, c_void};
|
||||
use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
|
||||
use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::memory::MemoryState;
|
||||
use crate::util::{
|
||||
check_stack, get_internal_userdata, init_internal_metatable, push_internal_userdata, push_string,
|
||||
push_table, rawset_field, to_string, TypeKey, DESTRUCTED_USERDATA_METATABLE,
|
||||
DESTRUCTED_USERDATA_METATABLE, TypeKey, check_stack, get_internal_userdata, init_internal_metatable,
|
||||
push_internal_userdata, push_string, push_table, rawset_field, to_string,
|
||||
};
|
||||
|
||||
static WRAPPED_FAILURE_TYPE_KEY: u8 = 0;
|
||||
|
||||
+6
-10
@@ -6,16 +6,16 @@ use std::{ptr, slice, str};
|
||||
use crate::error::{Error, Result};
|
||||
|
||||
pub(crate) use error::{
|
||||
error_traceback, error_traceback_thread, init_error_registry, pop_error, protect_lua_call,
|
||||
protect_lua_closure, WrappedFailure,
|
||||
WrappedFailure, error_traceback, error_traceback_thread, init_error_registry, pop_error,
|
||||
protect_lua_call, protect_lua_closure,
|
||||
};
|
||||
pub(crate) use path::parse_path as parse_lookup_path;
|
||||
pub(crate) use short_names::short_type_name;
|
||||
pub(crate) use types::TypeKey;
|
||||
pub(crate) use userdata::{
|
||||
get_destructed_userdata_metatable, get_internal_metatable, get_internal_userdata, get_userdata,
|
||||
init_internal_metatable, push_internal_userdata, push_userdata, take_userdata,
|
||||
DESTRUCTED_USERDATA_METATABLE,
|
||||
DESTRUCTED_USERDATA_METATABLE, get_destructed_userdata_metatable, get_internal_metatable,
|
||||
get_internal_userdata, get_userdata, init_internal_metatable, push_internal_userdata, push_userdata,
|
||||
take_userdata,
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "luau"))]
|
||||
@@ -264,11 +264,7 @@ pub(crate) unsafe fn get_main_state(state: *mut ffi::lua_State) -> Option<*mut f
|
||||
// Check the current state first
|
||||
let is_main_state = ffi::lua_pushthread(state) == 1;
|
||||
ffi::lua_pop(state, 1);
|
||||
if is_main_state {
|
||||
Some(state)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
if is_main_state { Some(state) } else { None }
|
||||
}
|
||||
#[cfg(feature = "luau")]
|
||||
Some(ffi::lua_mainthread(state))
|
||||
|
||||
+1
-1
@@ -196,7 +196,7 @@ fn unquote_string<'a>(path: &'a str, chars: &mut Peekable<CharIndices<'a>>) -> R
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{parse_path, PathKey};
|
||||
use super::{PathKey, parse_path};
|
||||
|
||||
#[test]
|
||||
fn test_parse_path() {
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::{mem, ptr};
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::userdata::collect_userdata;
|
||||
use crate::util::{check_stack, get_metatable_ptr, push_table, rawset_field, TypeKey};
|
||||
use crate::util::{TypeKey, check_stack, get_metatable_ptr, push_table, rawset_field};
|
||||
|
||||
// Pushes the userdata and attaches a metatable with __gc method.
|
||||
// Internally uses 3 stack spaces, does not call checkstack.
|
||||
|
||||
+15
-16
@@ -1,19 +1,18 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashSet;
|
||||
use std::os::raw::c_void;
|
||||
use std::string::String as StdString;
|
||||
use std::{fmt, ptr, str};
|
||||
|
||||
use num_traits::FromPrimitive;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::function::Function;
|
||||
use crate::string::{BorrowedStr, String};
|
||||
use crate::string::{BorrowedStr, LuaString};
|
||||
use crate::table::Table;
|
||||
use crate::thread::Thread;
|
||||
use crate::types::{Integer, LightUserData, Number, ValueRef};
|
||||
use crate::userdata::AnyUserData;
|
||||
use crate::util::{check_stack, StackGuard};
|
||||
use crate::util::{StackGuard, check_stack};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use {
|
||||
@@ -50,7 +49,7 @@ pub enum Value {
|
||||
/// An interned string, managed by Lua.
|
||||
///
|
||||
/// Unlike Rust strings, Lua strings may not be valid UTF-8.
|
||||
String(String),
|
||||
String(LuaString),
|
||||
/// Reference to a Lua table.
|
||||
Table(Table),
|
||||
/// Reference to a Lua function (or closure).
|
||||
@@ -129,7 +128,7 @@ impl Value {
|
||||
#[inline]
|
||||
pub fn to_pointer(&self) -> *const c_void {
|
||||
match self {
|
||||
Value::String(String(vref)) => {
|
||||
Value::String(LuaString(vref)) => {
|
||||
// In Lua < 5.4 (excluding Luau), string pointers are NULL
|
||||
// Use alternative approach
|
||||
let lua = vref.lua.lock();
|
||||
@@ -151,8 +150,8 @@ impl Value {
|
||||
///
|
||||
/// This might invoke the `__tostring` metamethod for non-primitive types (eg. tables,
|
||||
/// functions).
|
||||
pub fn to_string(&self) -> Result<StdString> {
|
||||
unsafe fn invoke_to_string(vref: &ValueRef) -> Result<StdString> {
|
||||
pub fn to_string(&self) -> Result<String> {
|
||||
unsafe fn invoke_to_string(vref: &ValueRef) -> Result<String> {
|
||||
let lua = vref.lua.lock();
|
||||
let state = lua.state();
|
||||
let _guard = StackGuard::new(state);
|
||||
@@ -162,7 +161,7 @@ impl Value {
|
||||
protect_lua!(state, 1, 1, fn(state) {
|
||||
ffi::luaL_tolstring(state, -1, ptr::null_mut());
|
||||
})?;
|
||||
Ok(String(lua.pop_ref()).to_str()?.to_string())
|
||||
Ok(LuaString(lua.pop_ref()).to_str()?.to_string())
|
||||
}
|
||||
|
||||
match self {
|
||||
@@ -336,17 +335,17 @@ impl Value {
|
||||
self.as_number()
|
||||
}
|
||||
|
||||
/// Returns `true` if the value is a Lua [`String`].
|
||||
/// Returns `true` if the value is a [`LuaString`].
|
||||
#[inline]
|
||||
pub fn is_string(&self) -> bool {
|
||||
self.as_string().is_some()
|
||||
}
|
||||
|
||||
/// Cast the value to Lua [`String`].
|
||||
/// Cast the value to a [`LuaString`].
|
||||
///
|
||||
/// If the value is a Lua [`String`], returns it or `None` otherwise.
|
||||
/// If the value is a [`LuaString`], returns it or `None` otherwise.
|
||||
#[inline]
|
||||
pub fn as_string(&self) -> Option<&String> {
|
||||
pub fn as_string(&self) -> Option<&LuaString> {
|
||||
match self {
|
||||
Value::String(s) => Some(s),
|
||||
_ => None,
|
||||
@@ -355,7 +354,7 @@ impl Value {
|
||||
|
||||
/// Cast the value to [`BorrowedStr`].
|
||||
///
|
||||
/// If the value is a Lua [`String`], try to convert it to [`BorrowedStr`] or return `None`
|
||||
/// If the value is a [`LuaString`], try to convert it to [`BorrowedStr`] or return `None`
|
||||
/// otherwise.
|
||||
#[deprecated(
|
||||
since = "0.11.0",
|
||||
@@ -366,15 +365,15 @@ impl Value {
|
||||
self.as_string().and_then(|s| s.to_str().ok())
|
||||
}
|
||||
|
||||
/// Cast the value to [`StdString`].
|
||||
/// Cast the value to [`String`].
|
||||
///
|
||||
/// If the value is a Lua [`String`], converts it to [`StdString`] or returns `None` otherwise.
|
||||
/// If the value is a [`LuaString`], converts it to [`String`] or returns `None` otherwise.
|
||||
#[deprecated(
|
||||
since = "0.11.0",
|
||||
note = "This method does not follow Rust naming convention. Use `as_string().map(|s| s.to_string_lossy())` instead."
|
||||
)]
|
||||
#[inline]
|
||||
pub fn as_string_lossy(&self) -> Option<StdString> {
|
||||
pub fn as_string_lossy(&self) -> Option<String> {
|
||||
self.as_string().map(|s| s.to_string_lossy())
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -1,6 +1,5 @@
|
||||
#![cfg(feature = "async")]
|
||||
|
||||
use std::string::String as StdString;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -40,7 +39,7 @@ async fn test_async_function() -> Result<()> {
|
||||
async fn test_async_function_wrap() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
let f = Function::wrap_async(|s: StdString| async move {
|
||||
let f = Function::wrap_async(|s: String| async move {
|
||||
tokio::task::yield_now().await;
|
||||
Ok(s)
|
||||
});
|
||||
@@ -68,7 +67,7 @@ async fn test_async_function_wrap() -> Result<()> {
|
||||
async fn test_async_function_wrap_raw() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
let f = Function::wrap_raw_async(|s: StdString| async move {
|
||||
let f = Function::wrap_raw_async(|s: String| async move {
|
||||
tokio::task::yield_now().await;
|
||||
s
|
||||
});
|
||||
|
||||
+17
-13
@@ -49,7 +49,7 @@ fn test_string_from_lua() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
// From stack
|
||||
let f = lua.create_function(|_, s: mlua::String| Ok(s))?;
|
||||
let f = lua.create_function(|_, s: mlua::LuaString| Ok(s))?;
|
||||
let s = f.call::<String>("hello, world!")?;
|
||||
assert_eq!(s, "hello, world!");
|
||||
|
||||
@@ -708,9 +708,10 @@ fn test_either_from_lua() -> Result<()> {
|
||||
},
|
||||
err => panic!("expected `Error::BadArgument`, got {err:?}"),
|
||||
}
|
||||
assert!(err
|
||||
.to_string()
|
||||
.starts_with("bad argument #1: error converting Lua string to Either<i32, Table>"),);
|
||||
assert!(
|
||||
err.to_string()
|
||||
.starts_with("bad argument #1: error converting Lua string to Either<i32, Table>"),
|
||||
);
|
||||
}
|
||||
err => panic!("expected `Error::CallbackError`, got {err:?}"),
|
||||
}
|
||||
@@ -736,15 +737,18 @@ fn test_char_from_lua() -> Result<()> {
|
||||
assert_eq!(lua.convert::<char>("A")?, 'A');
|
||||
assert_eq!(lua.convert::<char>(65)?, 'A');
|
||||
assert_eq!(lua.convert::<char>(128175)?, '💯');
|
||||
assert!(lua
|
||||
.convert::<char>(5456324)
|
||||
.is_err_and(|e| e.to_string().contains("integer out of range")));
|
||||
assert!(lua
|
||||
.convert::<char>("hello")
|
||||
.is_err_and(|e| e.to_string().contains("expected string to have exactly one char")));
|
||||
assert!(lua
|
||||
.convert::<char>(HashMap::<String, String>::new())
|
||||
.is_err_and(|e| e.to_string().contains("expected string or integer")));
|
||||
assert!(
|
||||
lua.convert::<char>(5456324)
|
||||
.is_err_and(|e| e.to_string().contains("integer out of range"))
|
||||
);
|
||||
assert!(
|
||||
lua.convert::<char>("hello")
|
||||
.is_err_and(|e| e.to_string().contains("expected string to have exactly one char"))
|
||||
);
|
||||
assert!(
|
||||
lua.convert::<char>(HashMap::<String, String>::new())
|
||||
.is_err_and(|e| e.to_string().contains("expected string or integer"))
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
use mlua::{Error, Function, Lua, Result, String, Table, Variadic};
|
||||
use mlua::{Error, Function, Lua, LuaString, Result, Table, Variadic};
|
||||
|
||||
#[test]
|
||||
fn test_function_call() -> Result<()> {
|
||||
@@ -267,7 +267,7 @@ fn test_function_coverage() -> Result<()> {
|
||||
|
||||
assert_eq!(
|
||||
report[0],
|
||||
mlua::CoverageInfo {
|
||||
mlua::function::CoverageInfo {
|
||||
function: None,
|
||||
line_defined: 1,
|
||||
depth: 0,
|
||||
@@ -276,7 +276,7 @@ fn test_function_coverage() -> Result<()> {
|
||||
);
|
||||
assert_eq!(
|
||||
report[1],
|
||||
mlua::CoverageInfo {
|
||||
mlua::function::CoverageInfo {
|
||||
function: Some("abc".into()),
|
||||
line_defined: 4,
|
||||
depth: 1,
|
||||
@@ -285,7 +285,7 @@ fn test_function_coverage() -> Result<()> {
|
||||
);
|
||||
assert_eq!(
|
||||
report[2],
|
||||
mlua::CoverageInfo {
|
||||
mlua::function::CoverageInfo {
|
||||
function: None,
|
||||
line_defined: 12,
|
||||
depth: 1,
|
||||
@@ -294,7 +294,7 @@ fn test_function_coverage() -> Result<()> {
|
||||
);
|
||||
assert_eq!(
|
||||
report[3],
|
||||
mlua::CoverageInfo {
|
||||
mlua::function::CoverageInfo {
|
||||
function: None,
|
||||
line_defined: 13,
|
||||
depth: 2,
|
||||
@@ -343,7 +343,7 @@ fn test_function_deep_clone() -> Result<()> {
|
||||
fn test_function_wrap() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
let f = Function::wrap(|s: String, n| Ok(s.to_str().unwrap().repeat(n)));
|
||||
let f = Function::wrap(|s: LuaString, n| Ok(s.to_str().unwrap().repeat(n)));
|
||||
lua.globals().set("f", f)?;
|
||||
lua.load(r#"assert(f("hello", 2) == "hellohello")"#)
|
||||
.exec()
|
||||
|
||||
+1
-1
@@ -3,8 +3,8 @@
|
||||
use std::cell::Cell;
|
||||
use std::fmt::Debug;
|
||||
use std::os::raw::c_void;
|
||||
use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU64, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU64, Ordering};
|
||||
|
||||
use mlua::{
|
||||
Compiler, Error, Function, Lua, LuaOptions, Result, StdLib, Table, ThreadStatus, Value, Vector, VmState,
|
||||
|
||||
+12
-6
@@ -42,8 +42,10 @@ fn test_require_errors() {
|
||||
// Pass non-string to require
|
||||
let res = run_require(&lua, true);
|
||||
assert!(res.is_err());
|
||||
assert!((res.unwrap_err().to_string())
|
||||
.contains("bad argument #1 to 'require' (string expected, got boolean)"));
|
||||
assert!(
|
||||
(res.unwrap_err().to_string())
|
||||
.contains("bad argument #1 to 'require' (string expected, got boolean)")
|
||||
);
|
||||
|
||||
// Require from loadstring
|
||||
let res = lua
|
||||
@@ -169,8 +171,10 @@ fn test_require_without_config() {
|
||||
"./tests/luau/require/without_config/ambiguous_file_requirer",
|
||||
);
|
||||
assert!(res.is_err());
|
||||
assert!((res.unwrap_err().to_string())
|
||||
.contains("could not resolve child component \"dependency\" (ambiguous)"));
|
||||
assert!(
|
||||
(res.unwrap_err().to_string())
|
||||
.contains("could not resolve child component \"dependency\" (ambiguous)")
|
||||
);
|
||||
|
||||
// RequireWithDirectoryAmbiguity
|
||||
let res = run_require(
|
||||
@@ -178,8 +182,10 @@ fn test_require_without_config() {
|
||||
"./tests/luau/require/without_config/ambiguous_directory_requirer",
|
||||
);
|
||||
assert!(res.is_err());
|
||||
assert!((res.unwrap_err().to_string())
|
||||
.contains("could not resolve child component \"dependency\" (ambiguous)"));
|
||||
assert!(
|
||||
(res.unwrap_err().to_string())
|
||||
.contains("could not resolve child component \"dependency\" (ambiguous)")
|
||||
);
|
||||
|
||||
// CheckCachedResult
|
||||
let res = run_require(&lua, "./tests/luau/require/without_config/validate_cache").unwrap();
|
||||
|
||||
+4
-2
@@ -1,4 +1,6 @@
|
||||
use mlua::{Error, ExternalError, Integer, IntoLuaMulti, Lua, MultiValue, Result, String, Value, Variadic};
|
||||
use mlua::{
|
||||
Error, ExternalError, Integer, IntoLuaMulti, Lua, LuaString, MultiValue, Result, Value, Variadic,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_result_conversions() -> Result<()> {
|
||||
@@ -81,7 +83,7 @@ fn test_multivalue_by_ref() -> Result<()> {
|
||||
Value::Boolean(true),
|
||||
]);
|
||||
|
||||
let f = lua.create_function(|_, (i, s, b): (i32, String, bool)| {
|
||||
let f = lua.create_function(|_, (i, s, b): (i32, LuaString, bool)| {
|
||||
assert_eq!(i, 3);
|
||||
assert_eq!(s.to_str()?, "hello");
|
||||
assert_eq!(b, true);
|
||||
|
||||
+7
-8
@@ -1,10 +1,9 @@
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
use std::string::String as StdString;
|
||||
use std::sync::Arc;
|
||||
|
||||
use mlua::{
|
||||
AnyUserData, Error, Function, Lua, MetaMethod, ObjectLike, Result, String, UserData, UserDataFields,
|
||||
AnyUserData, Error, Function, Lua, LuaString, MetaMethod, ObjectLike, Result, UserData, UserDataFields,
|
||||
UserDataMethods, UserDataRegistry,
|
||||
};
|
||||
|
||||
@@ -437,15 +436,15 @@ fn test_scope_userdata_ref_mut() -> Result<()> {
|
||||
fn test_scope_any_userdata() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
fn register(reg: &mut UserDataRegistry<&mut StdString>) {
|
||||
reg.add_method_mut("push", |_, this, s: String| {
|
||||
fn register(reg: &mut UserDataRegistry<&mut String>) {
|
||||
reg.add_method_mut("push", |_, this, s: LuaString| {
|
||||
this.push_str(&s.to_str()?);
|
||||
Ok(())
|
||||
});
|
||||
reg.add_meta_method("__tostring", |_, data, ()| Ok((*data).clone()));
|
||||
}
|
||||
|
||||
let mut data = StdString::from("foo");
|
||||
let mut data = String::from("foo");
|
||||
lua.scope(|scope| {
|
||||
let ud = scope.create_any_userdata(&mut data, register)?;
|
||||
lua.globals().set("ud", ud)?;
|
||||
@@ -527,11 +526,11 @@ fn test_scope_any_userdata_ref_mut() -> Result<()> {
|
||||
fn test_scope_destructors() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
lua.register_userdata_type::<Arc<StdString>>(|reg| {
|
||||
lua.register_userdata_type::<Arc<String>>(|reg| {
|
||||
reg.add_meta_method("__tostring", |_, data, ()| Ok(data.to_string()));
|
||||
})?;
|
||||
|
||||
let arc_str = Arc::new(StdString::from("foo"));
|
||||
let arc_str = Arc::new(String::from("foo"));
|
||||
|
||||
let ud = lua.create_any_userdata(arc_str.clone())?;
|
||||
lua.scope(|scope| {
|
||||
@@ -544,7 +543,7 @@ fn test_scope_destructors() -> Result<()> {
|
||||
|
||||
// Try destructing the userdata while it's borrowed
|
||||
let ud = lua.create_any_userdata(arc_str.clone())?;
|
||||
ud.borrow_scoped::<Arc<StdString>, _>(|arc_str| {
|
||||
ud.borrow_scoped::<Arc<String>, _>(|arc_str| {
|
||||
assert_eq!(arc_str.as_str(), "foo");
|
||||
lua.scope(|scope| {
|
||||
scope.add_destructor(|| {
|
||||
|
||||
+2
-3
@@ -2,7 +2,6 @@
|
||||
|
||||
use std::cell::UnsafeCell;
|
||||
use std::marker::PhantomData;
|
||||
use std::string::String as StdString;
|
||||
|
||||
use mlua::{AnyUserData, Error, Lua, ObjectLike, Result, UserData, UserDataMethods, UserDataRef};
|
||||
use static_assertions::{assert_impl_all, assert_not_impl_all};
|
||||
@@ -12,7 +11,7 @@ fn test_userdata_multithread_access_send_only() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
// This type is `Send` but not `Sync`.
|
||||
struct MyUserData(StdString, PhantomData<UnsafeCell<()>>);
|
||||
struct MyUserData(String, PhantomData<UnsafeCell<()>>);
|
||||
assert_impl_all!(MyUserData: Send);
|
||||
assert_not_impl_all!(MyUserData: Sync);
|
||||
|
||||
@@ -52,7 +51,7 @@ fn test_userdata_multithread_access_sync() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
// This type is `Send` and `Sync`.
|
||||
struct MyUserData(StdString);
|
||||
struct MyUserData(String);
|
||||
assert_impl_all!(MyUserData: Send, Sync);
|
||||
|
||||
impl UserData for MyUserData {
|
||||
|
||||
+10
-10
@@ -1,11 +1,11 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use mlua::{Lua, Result, String};
|
||||
use mlua::{Lua, LuaString, Result};
|
||||
|
||||
#[test]
|
||||
fn test_string_compare() {
|
||||
fn with_str<F: FnOnce(String)>(s: &str, f: F) {
|
||||
fn with_str<F: FnOnce(LuaString)>(s: &str, f: F) {
|
||||
f(Lua::new().create_string(s).unwrap());
|
||||
}
|
||||
|
||||
@@ -42,9 +42,9 @@ fn test_string_views() -> Result<()> {
|
||||
.exec()?;
|
||||
|
||||
let globals = lua.globals();
|
||||
let ok: String = globals.get("ok")?;
|
||||
let err: String = globals.get("err")?;
|
||||
let empty: String = globals.get("empty")?;
|
||||
let ok: LuaString = globals.get("ok")?;
|
||||
let err: LuaString = globals.get("err")?;
|
||||
let empty: LuaString = globals.get("empty")?;
|
||||
|
||||
assert_eq!(ok.to_str()?, "null bytes are valid utf-8, wh\0 knew?");
|
||||
assert_eq!(ok.to_string_lossy(), "null bytes are valid utf-8, wh\0 knew?");
|
||||
@@ -74,7 +74,7 @@ fn test_string_from_bytes() -> Result<()> {
|
||||
fn test_string_hash() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
let set: HashSet<String> = lua.load(r#"{"hello", "world", "abc", 321}"#).eval()?;
|
||||
let set: HashSet<LuaString> = lua.load(r#"{"hello", "world", "abc", 321}"#).eval()?;
|
||||
assert_eq!(set.len(), 4);
|
||||
assert!(set.contains(&lua.create_string("hello")?));
|
||||
assert!(set.contains(&lua.create_string("world")?));
|
||||
@@ -133,13 +133,13 @@ fn test_string_display() -> Result<()> {
|
||||
fn test_string_wrap() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
let s = String::wrap("hello, world");
|
||||
let s = LuaString::wrap("hello, world");
|
||||
lua.globals().set("s", s)?;
|
||||
assert_eq!(lua.globals().get::<String>("s")?, "hello, world");
|
||||
assert_eq!(lua.globals().get::<LuaString>("s")?, "hello, world");
|
||||
|
||||
let s2 = String::wrap("hello, world (owned)".to_string());
|
||||
let s2 = LuaString::wrap("hello, world (owned)".to_string());
|
||||
lua.globals().set("s2", s2)?;
|
||||
assert_eq!(lua.globals().get::<String>("s2")?, "hello, world (owned)");
|
||||
assert_eq!(lua.globals().get::<LuaString>("s2")?, "hello, world (owned)");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+29
-24
@@ -1,14 +1,13 @@
|
||||
use std::collections::HashMap;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use std::iter::FromIterator;
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
use std::string::String as StdString;
|
||||
use std::panic::{AssertUnwindSafe, catch_unwind};
|
||||
use std::sync::Arc;
|
||||
use std::{error, f32, f64, fmt};
|
||||
|
||||
use mlua::{
|
||||
ffi, ChunkMode, Error, ExternalError, Function, Lua, LuaOptions, Nil, Result, StdLib, String, Table,
|
||||
UserData, Value, Variadic,
|
||||
ChunkMode, Error, ExternalError, Function, Lua, LuaOptions, Nil, Result, StdLib, Table, UserData, Value,
|
||||
Variadic, ffi,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@@ -155,7 +154,7 @@ fn test_replace_globals() -> Result<()> {
|
||||
globals.set("foo", "bar")?;
|
||||
|
||||
lua.set_globals(globals.clone())?;
|
||||
let val = lua.load("return foo").eval::<StdString>()?;
|
||||
let val = lua.load("return foo").eval::<String>()?;
|
||||
assert_eq!(val, "bar");
|
||||
|
||||
// Updating globals in sandboxed Lua state is not allowed
|
||||
@@ -398,7 +397,7 @@ fn test_error() -> Result<()> {
|
||||
fn test_panic() -> Result<()> {
|
||||
fn make_lua(options: LuaOptions) -> Result<Lua> {
|
||||
let lua = Lua::new_with(StdLib::ALL_SAFE, options)?;
|
||||
let rust_panic_function = lua.create_function(|_, msg: Option<StdString>| -> Result<()> {
|
||||
let rust_panic_function = lua.create_function(|_, msg: Option<String>| -> Result<()> {
|
||||
if let Some(msg) = msg {
|
||||
panic!("{}", msg)
|
||||
}
|
||||
@@ -496,7 +495,7 @@ fn test_panic() -> Result<()> {
|
||||
.exec()
|
||||
}) {
|
||||
Ok(r) => panic!("no panic was detected: {:?}", r),
|
||||
Err(p) => assert!(*p.downcast::<StdString>().unwrap() == "rust panic from lua"),
|
||||
Err(p) => assert!(*p.downcast::<String>().unwrap() == "rust panic from lua"),
|
||||
}
|
||||
|
||||
// Test disabling `catch_rust_panics` option / xpcall correctness
|
||||
@@ -520,7 +519,7 @@ fn test_panic() -> Result<()> {
|
||||
.exec()
|
||||
}) {
|
||||
Ok(r) => panic!("no panic was detected: {:?}", r),
|
||||
Err(p) => assert!(*p.downcast::<StdString>().unwrap() == "rust panic from lua"),
|
||||
Err(p) => assert!(*p.downcast::<String>().unwrap() == "rust panic from lua"),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -684,10 +683,12 @@ fn test_pcall_xpcall() -> Result<()> {
|
||||
))]
|
||||
assert_eq!(globals.get::<std::string::String>("xpcall_error")?, "testerror");
|
||||
#[cfg(feature = "lua51")]
|
||||
assert!(globals
|
||||
.get::<String>("xpcall_error")?
|
||||
.to_str()?
|
||||
.ends_with(": testerror"));
|
||||
assert!(
|
||||
globals
|
||||
.get::<mlua::LuaString>("xpcall_error")?
|
||||
.to_str()?
|
||||
.ends_with(": testerror")
|
||||
);
|
||||
|
||||
// Make sure that weird xpcall error recursion at least doesn't cause unsafety or panics.
|
||||
lua.load(
|
||||
@@ -1070,10 +1071,11 @@ fn test_ref_stack_exhaustion() {
|
||||
Ok(())
|
||||
})) {
|
||||
Ok(_) => panic!("no panic was detected"),
|
||||
Err(p) => assert!(p
|
||||
.downcast::<StdString>()
|
||||
.unwrap()
|
||||
.starts_with("cannot create a Lua reference, out of auxiliary stack space")),
|
||||
Err(p) => assert!(
|
||||
p.downcast::<String>()
|
||||
.unwrap()
|
||||
.starts_with("cannot create a Lua reference, out of auxiliary stack space")
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1218,7 +1220,11 @@ fn test_context_thread_51() -> Result<()> {
|
||||
fn test_jit_version() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
let jit: Table = lua.globals().get("jit")?;
|
||||
assert!(jit.get::<String>("version")?.to_str()?.contains("LuaJIT"));
|
||||
assert!(
|
||||
jit.get::<mlua::LuaString>("version")?
|
||||
.to_str()?
|
||||
.contains("LuaJIT")
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1318,7 +1324,7 @@ fn test_inspect_stack() -> Result<()> {
|
||||
// Not inside any function
|
||||
assert!(lua.inspect_stack(0, |_| ()).is_none());
|
||||
|
||||
let logline = lua.create_function(|lua, msg: StdString| {
|
||||
let logline = lua.create_function(|lua, msg: String| {
|
||||
let r = lua
|
||||
.inspect_stack(1, |debug| {
|
||||
let source = debug.source().short_src;
|
||||
@@ -1422,9 +1428,8 @@ fn test_traceback() -> Result<()> {
|
||||
assert!(traceback.contains("stack traceback:"));
|
||||
|
||||
// Test traceback inside a function
|
||||
let get_traceback = lua.create_function(|lua, (msg, level): (Option<StdString>, usize)| {
|
||||
lua.traceback(msg.as_deref(), level)
|
||||
})?;
|
||||
let get_traceback = lua
|
||||
.create_function(|lua, (msg, level): (Option<String>, usize)| lua.traceback(msg.as_deref(), level))?;
|
||||
lua.globals().set("get_traceback", get_traceback)?;
|
||||
|
||||
lua.load(
|
||||
@@ -1504,10 +1509,10 @@ fn test_multi_states() -> Result<()> {
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
fn test_warnings() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
lua.set_app_data::<Vec<(StdString, bool)>>(Vec::new());
|
||||
lua.set_app_data::<Vec<(String, bool)>>(Vec::new());
|
||||
|
||||
lua.set_warning_function(|lua, msg, incomplete| {
|
||||
lua.app_data_mut::<Vec<(StdString, bool)>>()
|
||||
lua.app_data_mut::<Vec<(String, bool)>>()
|
||||
.unwrap()
|
||||
.push((msg.to_string(), incomplete));
|
||||
Ok(())
|
||||
@@ -1521,7 +1526,7 @@ fn test_warnings() -> Result<()> {
|
||||
lua.remove_warning_function();
|
||||
lua.warning("one more warning", false);
|
||||
|
||||
let messages = lua.app_data_ref::<Vec<(StdString, bool)>>().unwrap();
|
||||
let messages = lua.app_data_ref::<Vec<(String, bool)>>().unwrap();
|
||||
assert_eq!(
|
||||
*messages,
|
||||
vec![
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
use std::os::raw::c_void;
|
||||
|
||||
use mlua::{Function, LightUserData, Lua, Number, Result, String as LuaString, Thread};
|
||||
use mlua::{Function, LightUserData, Lua, LuaString, Number, Result, Thread};
|
||||
|
||||
#[test]
|
||||
fn test_lightuserdata() -> Result<()> {
|
||||
|
||||
+28
-23
@@ -1,14 +1,13 @@
|
||||
use std::any::TypeId;
|
||||
use std::collections::HashMap;
|
||||
use std::string::String as StdString;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[cfg(any(feature = "lua55", feature = "lua54"))]
|
||||
use std::sync::atomic::{AtomicI64, Ordering};
|
||||
|
||||
use mlua::{
|
||||
AnyUserData, Error, ExternalError, Function, Lua, MetaMethod, Nil, ObjectLike, Result, String, UserData,
|
||||
UserDataFields, UserDataMethods, UserDataRef, UserDataRegistry, Value, Variadic,
|
||||
AnyUserData, Error, ExternalError, Function, Lua, LuaString, MetaMethod, Nil, ObjectLike, Result,
|
||||
UserData, UserDataFields, UserDataMethods, UserDataRef, UserDataRegistry, Value, Variadic,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@@ -131,7 +130,7 @@ fn test_metamethods() -> Result<()> {
|
||||
MetaMethod::Eq,
|
||||
|_, (lhs, rhs): (UserDataRef<Self>, UserDataRef<Self>)| Ok(lhs.0 == rhs.0),
|
||||
);
|
||||
methods.add_meta_method(MetaMethod::Index, |_, data, index: String| {
|
||||
methods.add_meta_method(MetaMethod::Index, |_, data, index: LuaString| {
|
||||
if index.to_str()? == "inner" {
|
||||
Ok(data.0)
|
||||
} else {
|
||||
@@ -291,8 +290,8 @@ fn test_gc_userdata() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
lua.globals().set("userdata", MyUserdata { id: 123 })?;
|
||||
|
||||
assert!(lua
|
||||
.load(
|
||||
assert!(
|
||||
lua.load(
|
||||
r#"
|
||||
local tbl = setmetatable({
|
||||
userdata = userdata
|
||||
@@ -308,7 +307,8 @@ fn test_gc_userdata() -> Result<()> {
|
||||
"#
|
||||
)
|
||||
.exec()
|
||||
.is_err());
|
||||
.is_err()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -491,8 +491,8 @@ fn test_user_values() -> Result<()> {
|
||||
ud.set_nth_user_value(1, "hello")?;
|
||||
ud.set_nth_user_value(2, "world")?;
|
||||
ud.set_nth_user_value(65535, 321)?;
|
||||
assert_eq!(ud.nth_user_value::<String>(1)?, "hello");
|
||||
assert_eq!(ud.nth_user_value::<String>(2)?, "world");
|
||||
assert_eq!(ud.nth_user_value::<LuaString>(1)?, "hello");
|
||||
assert_eq!(ud.nth_user_value::<LuaString>(2)?, "world");
|
||||
assert_eq!(ud.nth_user_value::<Value>(3)?, Value::Nil);
|
||||
assert_eq!(ud.nth_user_value::<i32>(65535)?, 321);
|
||||
|
||||
@@ -582,8 +582,8 @@ fn test_fields() -> Result<()> {
|
||||
});
|
||||
|
||||
// Use userdata "uservalue" storage
|
||||
fields.add_field_function_get("uval", |_, ud| ud.user_value::<Option<String>>());
|
||||
fields.add_field_function_set("uval", |_, ud, s: Option<String>| ud.set_user_value(s));
|
||||
fields.add_field_function_get("uval", |_, ud| ud.user_value::<Option<LuaString>>());
|
||||
fields.add_field_function_set("uval", |_, ud, s: Option<LuaString>| ud.set_user_value(s));
|
||||
|
||||
fields.add_meta_field(MetaMethod::Index, HashMap::from([("f", 321)]));
|
||||
fields.add_meta_field_with(MetaMethod::NewIndex, |lua| {
|
||||
@@ -630,9 +630,11 @@ fn test_fields() -> Result<()> {
|
||||
}
|
||||
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(MetaMethod::Index, |_, _, name: StdString| match &*name {
|
||||
"y" => Ok(Some(-1)),
|
||||
_ => Ok(None),
|
||||
methods.add_meta_method(MetaMethod::Index, |_, _, name: LuaString| {
|
||||
match name.to_str()?.as_ref() {
|
||||
"y" => Ok(Some(-1)),
|
||||
_ => Ok(None),
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -659,7 +661,7 @@ fn test_metatable() -> Result<()> {
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_function("my_type_name", |_, data: AnyUserData| {
|
||||
let metatable = data.metatable()?;
|
||||
metatable.get::<String>(MetaMethod::Type)
|
||||
metatable.get::<LuaString>(MetaMethod::Type)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -723,7 +725,10 @@ fn test_metatable() -> Result<()> {
|
||||
|
||||
let ud = lua.create_userdata(MyUserData3)?;
|
||||
let metatable = ud.metatable()?;
|
||||
assert_eq!(metatable.get::<String>(MetaMethod::Type)?.to_str()?, "CustomName");
|
||||
assert_eq!(
|
||||
metatable.get::<LuaString>(MetaMethod::Type)?.to_str()?,
|
||||
"CustomName"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -776,16 +781,16 @@ fn test_userdata_proxy() -> Result<()> {
|
||||
fn test_any_userdata() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
lua.register_userdata_type::<StdString>(|reg| {
|
||||
lua.register_userdata_type::<String>(|reg| {
|
||||
reg.add_method("get", |_, this, ()| Ok(this.clone()));
|
||||
reg.add_method_mut("concat", |_, this, s: String| {
|
||||
reg.add_method_mut("concat", |_, this, s: LuaString| {
|
||||
this.push_str(&s.to_string_lossy());
|
||||
Ok(())
|
||||
});
|
||||
})?;
|
||||
|
||||
let ud = lua.create_any_userdata("hello".to_string())?;
|
||||
assert_eq!(&*ud.borrow::<StdString>()?, "hello");
|
||||
assert_eq!(&*ud.borrow::<String>()?, "hello");
|
||||
|
||||
lua.globals().set("ud", ud)?;
|
||||
lua.load(
|
||||
@@ -805,7 +810,7 @@ fn test_any_userdata() -> Result<()> {
|
||||
fn test_any_userdata_wrap() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
lua.register_userdata_type::<StdString>(|reg| {
|
||||
lua.register_userdata_type::<String>(|reg| {
|
||||
reg.add_method("get", |_, this, ()| Ok(this.clone()));
|
||||
})?;
|
||||
|
||||
@@ -857,7 +862,7 @@ fn test_userdata_object_like() -> Result<()> {
|
||||
r => panic!("expected RuntimeError, got {r:?}"),
|
||||
}
|
||||
|
||||
assert_eq!(ud.call::<String>(())?, "called");
|
||||
assert_eq!(ud.call::<LuaString>(())?, "called");
|
||||
|
||||
ud.call_method::<()>("add", 2)?;
|
||||
assert_eq!(ud.get::<u32>("n")?, 323);
|
||||
@@ -1375,7 +1380,7 @@ fn test_userdata_namecall() -> Result<()> {
|
||||
registry.add_method("method", |_, _, ()| Ok("method called"));
|
||||
registry.add_field_method_get("field", |_, _| Ok("field value"));
|
||||
|
||||
registry.add_meta_method(MetaMethod::Index, |_, _, key: StdString| Ok(key));
|
||||
registry.add_meta_method(MetaMethod::Index, |_, _, key: LuaString| Ok(key));
|
||||
|
||||
registry.enable_namecall();
|
||||
}
|
||||
@@ -1413,7 +1418,7 @@ fn test_userdata_get_path() -> Result<()> {
|
||||
}
|
||||
|
||||
let ud = lua.create_userdata(MyUd)?;
|
||||
assert_eq!(ud.get_path::<String>(".value")?, "userdata_value");
|
||||
assert_eq!(ud.get_path::<LuaString>(".value")?, "userdata_value");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+8
-7
@@ -1,7 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
use std::os::raw::c_void;
|
||||
use std::ptr;
|
||||
use std::string::String as StdString;
|
||||
|
||||
use mlua::{Error, LightUserData, Lua, MultiValue, Result, UserData, UserDataMethods, Value};
|
||||
|
||||
@@ -178,7 +177,7 @@ fn test_value_to_string() -> Result<()> {
|
||||
assert!(thread.to_string()?.starts_with("thread:"));
|
||||
assert_eq!(thread.type_name(), "thread");
|
||||
|
||||
lua.register_userdata_type::<StdString>(|reg| {
|
||||
lua.register_userdata_type::<String>(|reg| {
|
||||
reg.add_meta_method("__tostring", |_, this, ()| Ok(this.clone()));
|
||||
})?;
|
||||
let ud: Value = Value::UserData(lua.create_any_userdata(String::from("string userdata"))?);
|
||||
@@ -213,9 +212,9 @@ fn test_value_to_string() -> Result<()> {
|
||||
fn test_debug_format() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
lua.register_userdata_type::<HashMap<i32, StdString>>(|_| {})?;
|
||||
lua.register_userdata_type::<HashMap<i32, String>>(|_| {})?;
|
||||
let ud = lua
|
||||
.create_any_userdata::<HashMap<i32, StdString>>(HashMap::new())
|
||||
.create_any_userdata::<HashMap<i32, String>>(HashMap::new())
|
||||
.map(Value::UserData)?;
|
||||
assert!(format!("{ud:#?}").starts_with("HashMap<i32, String>:"));
|
||||
|
||||
@@ -259,9 +258,11 @@ fn test_value_conversions() -> Result<()> {
|
||||
assert!(Value::Table(lua.create_table()?).is_table());
|
||||
assert!(Value::Table(lua.create_table()?).as_table().is_some());
|
||||
assert!(Value::Function(lua.create_function(|_, ()| Ok(())).unwrap()).is_function());
|
||||
assert!(Value::Function(lua.create_function(|_, ()| Ok(())).unwrap())
|
||||
.as_function()
|
||||
.is_some());
|
||||
assert!(
|
||||
Value::Function(lua.create_function(|_, ()| Ok(())).unwrap())
|
||||
.as_function()
|
||||
.is_some()
|
||||
);
|
||||
assert!(Value::Thread(lua.create_thread(lua.load("function() end").eval()?)?).is_thread());
|
||||
assert!(
|
||||
Value::Thread(lua.create_thread(lua.load("function() end").eval()?)?)
|
||||
|
||||
Reference in New Issue
Block a user