1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use crate::{compiler::BytecodeCompiler, lua::LuaInt};

pub type Bytecode = Vec<u8>;

#[derive(Debug, Clone)]
pub enum LuaError {
	/// Out of memory
	///
	/// `LUA_ERRMEM`
	MemoryAllocationError,

	/// A syntax error occurred in the passed Lua source code.
	///
	/// `LUA_ERRSYNTAX`
	SyntaxError(Option<String>),

	/// Lua failed to load the given file
	///
	/// `LUA_ERRFILE`
	FileError(Option<String>),

	/// A runtime error occurred while compiling bytecode.
	///
	/// `LUA_ERRRUN`
	RuntimeError(Option<String>),

	/// An error occurred while running the error handler function.
	///
	/// `LUA_ERRERR`
	ErrorHandlerError,

	/// Unknown Lua error code
	Unknown(LuaInt),

	#[cfg(not(feature = "parking_lot"))]
	/// The Mutex guarding the Lua state is poisoned by a panic in another thread.
	PoisonError,
}

/// Creates a new bytecode compiler instance.
///
/// When dropped, it will close the Lua state and free any used dynamic memory.
///
/// ## Thread safety
/// The bytecode compiler instance's Lua state is locked behind a Mutex to ensure concurrency safety.
pub fn compiler() -> Result<BytecodeCompiler, LuaError> {
	unsafe { BytecodeCompiler::new() }
}

/// Converts a string literal to a Lua-compatible NUL terminated `CString`.
///
/// Also can convert a `String` or `&str` to a Lua-compatible NUL terminated `CString`.
///
/// **You must not add any NUL bytes into this string yourself.**
#[macro_export]
macro_rules! lua_string {
	( $str:literal ) => {
		#[allow(unused_unsafe)]
		unsafe { std::ffi::CStr::from_bytes_with_nul_unchecked(concat!($str, "\0").as_bytes()).as_ptr() }
	};

	( $str:expr ) => {
		std::ffi::CString::new($str).expect("Tried to create a Lua string from a string that contained a NUL byte (\\0)!").as_ptr()
	}
}