Skip to main content

low_luajit/lua/type/
boolean.rs

1use crate::{AmountReturned, LuaState, ffi};
2
3const fn likely(b: bool) -> bool {
4	if !b {
5		#[cfg(feature = "no_msrv")]
6		#[clippy::msrv = "1.95.0"]
7		core::hint::cold_path();
8	}
9
10	b
11}
12
13/// Boolean related functions.
14impl LuaState {
15	/// Returns `true` if the value at the given acceptable `index` is a boolean, `false` otherwise.
16	#[inline]
17	#[must_use]
18	pub fn is_boolean(&self, index: i32) -> bool {
19		// SAFETY: self.as_ptr() is always valid.
20		unsafe { ffi::lua_isboolean(self.as_ptr(), index) != 0 }
21	}
22
23	/// Converts the value at the given acceptable `index` to a boolean and returns it.
24	///
25	/// Any value besides `false` or `nil` is converted to `true`, `false` otherwise.
26	///
27	/// This conversion *does not* affect the element in the stack itself (it stays as is).
28	#[inline]
29	#[must_use]
30	pub fn to_boolean(&self, index: i32) -> bool {
31		// SAFETY: self.as_ptr() is always valid.
32		unsafe { ffi::lua_toboolean(self.as_ptr(), index) != 0 }
33	}
34
35	/// Pushes the given `boolean` onto the stack.
36	#[inline]
37	#[allow(clippy::must_use_candidate)]
38	pub fn push_boolean(&mut self, boolean: bool) {
39		// SAFETY: self.as_ptr() is always valid.
40		unsafe { ffi::lua_pushboolean(self.as_ptr(), i32::from(boolean)); }
41	}
42
43	/// Checks if there's a boolean at the given index `arg_n` and returns it.
44	///
45	/// If the check fails, [`LuaState::type_error`] is called using `arg_n`.
46	///
47	/// # Lua Errors
48	///
49	/// Intentionally errors if the check fails.
50	#[inline]
51	#[allow(clippy::must_use_candidate)]
52	pub fn check_boolean(&self, arg_n: i32) -> bool {
53		if likely(self.is_boolean(arg_n)) {
54			self.to_boolean(arg_n)
55		} else {
56			self.type_error(arg_n, c"boolean");
57		}
58	}
59
60	/// Behaves exactly as [`LuaState::check_boolean`],
61	/// but returns `default` instead of erroring when the element at the given index `arg_n` is `nil` (or non-existing).
62	#[inline]
63	#[allow(clippy::must_use_candidate)]
64	pub fn opt_boolean(&self, arg_n: i32, default: bool) -> bool {
65		if likely(self.is_boolean(arg_n)) {
66			self.to_boolean(arg_n)
67		} else if self.is_none_or_nil(arg_n) {
68			default
69		} else {
70			self.type_error(arg_n, c"boolean");
71		}
72	}
73
74	/// Finishes the currently called [`CFunction`], returning the given `boolean` to the caller.
75	///
76	/// The `LuaState` wrapper is consumed to prevent invalidating the `AmountReturned` (the Lua state itself is left intact).
77	///
78	/// [`CFunction`]: ./type.CFunction.html
79	#[inline]
80	pub fn return_boolean(mut self, boolean: bool) -> AmountReturned {
81		self.push_boolean(boolean);
82
83		// SAFETY: There should always be at least one element in the stack.
84		unsafe { AmountReturned::unchecked(1) }
85	}
86}