Skip to main content

low_luajit/lua/type/
number.rs

1use crate::{AmountReturned, LuaState, ffi};
2
3/// Number related functions.
4impl LuaState {
5	/// Returns `true` if the value at the given acceptable `index` is a number, `false` otherwise.
6	#[inline]
7	#[must_use]
8	pub fn is_number(&self, index: i32) -> bool {
9		// SAFETY: self.as_ptr() is always valid.
10		unsafe { ffi::lua_isnumber(self.as_ptr(), index) != 0 }
11	}
12
13	/// Converts the value at the given acceptable `index` to a number and returns it.
14	///
15	/// Only numbers or strings that can be converted into numbers are accepted. Anything else will return `0.0`.
16	///
17	/// This conversion *does not* affect the element in the stack itself (it stays as is).
18	#[inline]
19	#[must_use]
20	pub fn to_number(&self, index: i32) -> f64 {
21		// SAFETY: self.as_ptr() is always valid.
22		unsafe { ffi::lua_tonumber(self.as_ptr(), index) }
23	}
24
25	/// Converts the value at the given acceptable `index` to a number and returns it.
26	///
27	/// Only numbers or strings that can be converted into numbers are accepted. Anything else will return `None`.
28	///
29	/// This conversion *does not* affect the element in the stack itself (it stays as is).
30	#[inline]
31	#[must_use]
32	pub fn to_number_x(&self, index: i32) -> Option<f64> {
33		// SAFETY: self.as_ptr() is always valid and is_num is initialized right before passing its pointer.
34		let mut is_num = 0;
35		let number = unsafe { ffi::lua_tonumberx(self.as_ptr(), index, &raw mut is_num) };
36		(is_num != 0).then_some(number)
37	}
38
39	/// Converts the value at the given acceptable `index` to an integer and returns it.
40	///
41	/// Only numbers or strings that can be converted into numbers are accepted. Anything else will return `0`.
42	///
43	/// If the number is not an integer, it will be truncated in an unspecified way.
44	///
45	/// This conversion *does not* affect the element in the stack itself (it stays as is).
46	#[inline]
47	#[must_use]
48	pub fn to_integer(&self, index: i32) -> isize {
49		// SAFETY: self.as_ptr() is always valid.
50		unsafe { ffi::lua_tointeger(self.as_ptr(), index) }
51	}
52
53	/// Converts the value at the given acceptable `index` to an integer and returns it.
54	///
55	/// Only numbers or strings that can be converted into numbers are accepted. Anything else will return `0`.
56	///
57	/// If the number is not an integer, it will be truncated in an unspecified way.
58	///
59	/// This conversion *does not* affect the element in the stack itself (it stays as is).
60	#[inline]
61	#[must_use]
62	pub fn to_integer_x(&self, index: i32) -> Option<isize> {
63		// SAFETY: self.as_ptr() is always valid.
64		let mut is_num = 0;
65		let integer = unsafe { ffi::lua_tointegerx(self.as_ptr(), index, &raw mut is_num) };
66		(is_num != 0).then_some(integer)
67	}
68
69	/// Pushes the given `number` onto the stack.
70	#[inline]
71	pub fn push_number(&mut self, number: f64) {
72		// SAFETY: self.as_ptr() is always valid.
73		unsafe { ffi::lua_pushnumber(self.as_ptr(), number); }
74	}
75
76	/// Pushes the given `integer` onto the stack.
77	#[inline]
78	pub fn push_integer(&mut self, integer: isize) {
79		// SAFETY: self.as_ptr() is always valid.
80		unsafe { ffi::lua_pushinteger(self.as_ptr(), integer); }
81	}
82
83	/// Checks if there's a number at the given index `arg_n` and returns it.
84	///
85	/// If the check fails, [`LuaState::type_error`] is called using `arg_n`.
86	///
87	/// # Lua Errors
88	///
89	/// Intentionally errors if the check fails.
90	#[inline]
91	#[allow(clippy::must_use_candidate)]
92	pub fn check_number(&self, arg_n: i32) -> f64 {
93		// SAFETY: self.as_ptr() is always valid.
94		unsafe { ffi::luaL_checknumber(self.as_ptr(), arg_n) }
95	}
96
97	/// Checks if there's a number at the given index `arg_n` and returns it as an integer.
98	///
99	/// If the check fails, [`LuaState::type_error`] is called using `arg_n`.
100	///
101	/// # Lua Errors
102	///
103	/// Intentionally errors if the check fails.
104	#[inline]
105	#[allow(clippy::must_use_candidate)]
106	pub fn check_integer(&self, arg_n: i32) -> isize {
107		// SAFETY: self.as_ptr() is always valid.
108		unsafe { ffi::luaL_checkinteger(self.as_ptr(), arg_n) }
109	}
110
111	/// Behaves exactly as [`LuaState::check_number`],
112	/// but returns `default` instead of erroring when the element at the given index `arg_n` is `nil` (or non-existing).
113	#[inline]
114	#[allow(clippy::must_use_candidate)]
115	pub fn opt_number(&self, arg_n: i32, default: f64) -> f64 {
116		// SAFETY: self.as_ptr() is always valid.
117		unsafe { ffi::luaL_optnumber(self.as_ptr(), arg_n, default) }
118	}
119
120	/// Behaves exactly as [`LuaState::check_integer`],
121	/// but returns `default` instead of erroring when the element at the given index `arg_n` is `nil` (or non-existing).
122	#[inline]
123	#[allow(clippy::must_use_candidate)]
124	pub fn opt_integer(&self, arg_n: i32, default: isize) -> isize {
125		// SAFETY: self.as_ptr() is always valid.
126		unsafe { ffi::luaL_optinteger(self.as_ptr(), arg_n, default) }
127	}
128
129	/// Finishes the currently called [`CFunction`], returning the given `number` to the caller.
130	///
131	/// The `LuaState` wrapper is consumed to prevent invalidating the `AmountReturned` (the Lua state itself is left intact).
132	///
133	/// [`CFunction`]: ./type.CFunction.html
134	#[inline]
135	pub fn return_number(mut self, number: f64) -> AmountReturned {
136		self.push_number(number);
137
138		// SAFETY: There should always be at least one element in the stack.
139		unsafe { AmountReturned::unchecked(1) }
140	}
141
142	/// Finishes the currently called [`CFunction`], returning the given `integer` to the caller.
143	///
144	/// The `LuaState` wrapper is consumed to prevent invalidating the `AmountReturned` (the Lua state itself is left intact).
145	///
146	/// [`CFunction`]: ./type.CFunction.html
147	#[inline]
148	pub fn return_integer(mut self, integer: isize) -> AmountReturned {
149		self.push_integer(integer);
150
151		// SAFETY: There should always be at least one element in the stack.
152		unsafe { AmountReturned::unchecked(1) }
153	}
154}