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}