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.0 is always valid.
10		unsafe { ffi::lua_isnumber(self.0, 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.0 is always valid.
22		unsafe { ffi::lua_tonumber(self.0, 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.0 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.0, 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.0 is always valid.
50		unsafe { ffi::lua_tointeger(self.0, 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.0 is always valid.
64		let mut is_num = 0;
65		let integer = unsafe { ffi::lua_tointegerx(self.0, 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.0 is always valid.
73		unsafe { ffi::lua_pushnumber(self.0, 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.0 is always valid.
80		unsafe { ffi::lua_pushinteger(self.0, 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	pub fn check_number(&self, arg_n: i32) -> f64 {
92		// SAFETY: self.0 is always valid.
93		unsafe { ffi::luaL_checknumber(self.0, arg_n) }
94	}
95
96	/// Checks if there's a number at the given index `arg_n` and returns it as an integer.
97	///
98	/// If the check fails, [`LuaState::type_error`] is called using `arg_n`.
99	///
100	/// # Lua Errors
101	///
102	/// Intentionally errors if the check fails.
103	#[inline]
104	pub fn check_integer(&self, arg_n: i32) -> isize {
105		// SAFETY: self.0 is always valid.
106		unsafe { ffi::luaL_checkinteger(self.0, arg_n) }
107	}
108
109	/// Behaves exactly as [`LuaState::check_number`],
110	/// but returns `default` instead of erroring when the element at the given index `arg_n` is `nil` (or non-existing).
111	#[inline]
112	pub fn opt_number(&self, arg_n: i32, default: f64) -> f64 {
113		// SAFETY: self.0 is always valid.
114		unsafe { ffi::luaL_optnumber(self.0, arg_n, default) }
115	}
116
117	/// Behaves exactly as [`LuaState::check_integer`],
118	/// but returns `default` instead of erroring when the element at the given index `arg_n` is `nil` (or non-existing).
119	#[inline]
120	pub fn opt_integer(&self, arg_n: i32, default: isize) -> isize {
121		// SAFETY: self.0 is always valid.
122		unsafe { ffi::luaL_optinteger(self.0, arg_n, default) }
123	}
124
125	/// Finishes the currently called [`CFunction`], returning the given `number` to the caller.
126	///
127	/// The `LuaState` wrapper is consumed to prevent invalidating the `AmountReturned` (the Lua state itself is left intact).
128	///
129	/// [`CFunction`]: ./type.CFunction.html
130	#[inline]
131	pub fn return_number(mut self, number: f64) -> AmountReturned {
132		self.push_number(number);
133
134		// SAFETY: There should always be at least one element in the stack.
135		unsafe { AmountReturned::unchecked(1) }
136	}
137
138	/// Finishes the currently called [`CFunction`], returning the given `integer` to the caller.
139	///
140	/// The `LuaState` wrapper is consumed to prevent invalidating the `AmountReturned` (the Lua state itself is left intact).
141	///
142	/// [`CFunction`]: ./type.CFunction.html
143	#[inline]
144	pub fn return_integer(mut self, integer: isize) -> AmountReturned {
145		self.push_integer(integer);
146
147		// SAFETY: There should always be at least one element in the stack.
148		unsafe { AmountReturned::unchecked(1) }
149	}
150}