low-luajit 0.3.1

Low level but safe bindings to the LuaJIT C API with no dependencies and no-std support to create Lua modules using Rust.
Documentation
use core::ptr;

use crate::ffi::{self, lua_State};

/// Opaque container of the state of a Lua interpreter and entry point to the LuaJIT C API.
///
/// See the [top-level documentation](index.html) for details on how to access `LuaState`.
///
/// Most functions assume you have a general understanding of the virtual stack the Lua interpreter uses.
/// If not, refer to [§3.1](https://www.lua.org/manual/5.1/manual.html#3.1) and [§3.2](https://www.lua.org/manual/5.1/manual.html#3.1).
///
/// A `LuaState` (and its wrapped pointer) should always be valid (unless unsafe constructors are used incorrectly) and will be treated as such.
///
/// *(Most of the methods' documentation below, and a few other places,
/// has been written using the [Lua 5.1 Reference Manual](https://www.lua.org/manual/5.1/manual.html) as reference:
/// Copyright © 2006–2012 Lua.org, PUC-Rio. Licensed under the [MIT license](https://www.lua.org/license.html).*)
#[repr(transparent)]
#[derive(Debug, PartialEq, Eq)]
pub struct LuaState(pub(super) *mut ffi::lua_State);

/// State handling functions.
impl LuaState {
	/* Not yet...
	/// Creates a new valid and independent Lua state.
	///
	/// This state will use the standard C `realloc` function as its allocator.
	///
	/// # Safety
	///
	/// While there is nothing inherently unsafe about creating a new `LuaState`,
	/// using the state without a protected environment could end badly in case a Lua error is triggered:
	/// at best, Rust simply aborts abruptly...but I've had segmentation faults happen sometimes too.
	#[inline]
	pub unsafe fn new_unchecked() -> Self {
		let ptr = unsafe { luaL_newstate() };
		assert!(!ptr.is_null(), "cannot create new Lua state: memory allocation error");
		Self(ptr)
	}*/

	/// Wraps a pre-existing raw [`lua_State`] pointer.
	///
	/// # Safety
	///
	/// `ptr` **must** be a valid pointer of an already existing state, as all other methods will assume it to be so.
	///
	/// Additionally, there must not be an existing accessible `LuaState` that is already using this pointer.
	#[must_use]
	pub const unsafe fn from_ptr(ptr: *mut lua_State) -> Self {
		Self(ptr)
	}

	/// Returns the underlying raw [`lua_State`] pointer.
	/// This can be used to pass the `LuaState` to raw [`ffi`] functions.
	///
	/// The caller must ensure that the `LuaState` outlives the pointer this function returns, or else it will end up dangling.
	///
	/// The returned pointer should also not be passed to functions that might invalidate the `LuaState` (like [`lua_close`]).
	///
	/// [`lua_close`]: ./ffi/fn.lua_close.html
	#[must_use]
	pub const fn as_ptr(&self) -> *mut lua_State {
		self.0
	}

	/// Destroys all objects and frees all dynamic memory of the state.
	///
	/// # Safety
	///
	/// Can only be called if this `LuaState` is not being used anywhere else.
	///
	/// If your crate is a Lua module, this function must *not* return back to the Lua interpreter (as it would no longer exist).
	#[inline]
	pub unsafe fn close(self) {
		// SAFETY: self.0 is always valid and the caller must make sure that the LuaState is not used anywhere else.
		unsafe { ffi::lua_close(self.0); }
	}

	/// Returns a reference to a number that represents the version of Lua.
	///
	/// For LuaJIT, this should always returns `501` (which represents 5.1, the Lua version LuaJIT is based on).
	#[inline]
	pub fn version() -> &'static f64 {
		// SAFETY: lua_version doesn't actually use the pointer given to it and always returns a valid pointer to a static f64.
		unsafe { &*ffi::lua_version(ptr::null_mut()) }
	}
}