Skip to main content

luaur_vm/functions/
lua_l_tolstring.rs

1//! Node: `cxx:Function:Luau.VM:VM/src/laux.cpp:616:luaL_tolstring`
2//! Source: `VM/src/laux.cpp:616-679` (hand-ported)
3
4use core::ffi::{c_char, c_int};
5
6use crate::enums::lua_type::lua_Type;
7use crate::functions::lua_encodepointer::lua_encodepointer;
8use crate::functions::lua_l_callmeta::lua_l_callmeta;
9use crate::functions::lua_l_error_l::lua_l_error_l;
10use crate::functions::lua_l_typename::lua_l_typename;
11use crate::functions::lua_pushfstring_l::lua_pushfstring_l;
12use crate::functions::lua_pushlstring::lua_pushlstring;
13use crate::functions::lua_pushstring::lua_pushstring;
14use crate::functions::lua_pushvalue::lua_pushvalue;
15use crate::functions::lua_toboolean::lua_toboolean;
16use crate::functions::lua_tointeger_64::lua_tointeger_64;
17use crate::functions::lua_tolstring::lua_tolstring;
18use crate::functions::lua_tonumberx::lua_tonumberx;
19use crate::functions::lua_topointer::lua_topointer;
20use crate::functions::lua_tovector::lua_tovector;
21use crate::functions::lua_type::lua_type;
22use crate::functions::luai_int_2_str::luai_int2str;
23use crate::functions::luai_num_2_str::luai_num2str;
24use crate::macros::lua_vector_size::LUA_VECTOR_SIZE;
25use crate::macros::luai_maxint_2_str::LUAI_MAXINT2STR;
26use crate::macros::luai_maxnum_2_str::LUAI_MAXNUM2STR;
27use crate::type_aliases::lua_state::lua_State;
28
29#[allow(non_snake_case)]
30pub unsafe fn lua_l_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char {
31    if lua_l_callmeta(L, idx, c"__tostring".as_ptr()) != 0 {
32        let s = lua_tolstring(L, -1, len);
33        if s.is_null() {
34            lua_l_error_l(
35                L,
36                c"'__tostring' must return a string".as_ptr(),
37                format_args!("'__tostring' must return a string"),
38            );
39        }
40        return s;
41    }
42
43    match lua_type(L, idx) {
44        x if x == lua_Type::LUA_TNIL as c_int => {
45            lua_pushlstring(L, c"nil".as_ptr(), 3);
46        }
47        x if x == lua_Type::LUA_TBOOLEAN as c_int => {
48            lua_pushstring(
49                L,
50                if lua_toboolean(L, idx) != 0 {
51                    c"true".as_ptr()
52                } else {
53                    c"false".as_ptr()
54                },
55            );
56        }
57        x if x == lua_Type::LUA_TNUMBER as c_int => {
58            let mut isnum = 0;
59            let n = lua_tonumberx(L, idx, &mut isnum);
60            let mut s = [0 as c_char; LUAI_MAXNUM2STR as usize];
61            let e = luai_num2str(s.as_mut_ptr(), n);
62            lua_pushlstring(L, s.as_ptr(), e.offset_from(s.as_ptr()) as usize);
63        }
64        x if x == lua_Type::LUA_TVECTOR as c_int => {
65            let v = lua_tovector(L, idx);
66            let mut s = [0 as c_char; (LUAI_MAXNUM2STR as usize) * (LUA_VECTOR_SIZE as usize)];
67            let mut e = s.as_mut_ptr();
68            let mut i = 0;
69            while i < LUA_VECTOR_SIZE {
70                if i != 0 {
71                    *e = b',' as c_char;
72                    e = e.add(1);
73                    *e = b' ' as c_char;
74                    e = e.add(1);
75                }
76                e = luai_num2str(e, *v.add(i as usize) as f64);
77                i += 1;
78            }
79            lua_pushlstring(L, s.as_ptr(), e.offset_from(s.as_ptr()) as usize);
80        }
81        x if x == lua_Type::LUA_TSTRING as c_int => {
82            lua_pushvalue(L, idx);
83        }
84        x if x == lua_Type::LUA_TINTEGER as c_int => {
85            let l = lua_tointeger_64(L, idx, core::ptr::null_mut());
86            let mut s = [0 as c_char; LUAI_MAXINT2STR as usize];
87            let e = luai_int2str(s.as_mut_ptr(), l);
88            lua_pushlstring(L, s.as_ptr(), e.offset_from(s.as_ptr()) as usize);
89        }
90        _ => {
91            let ptr = lua_topointer(L, idx);
92            let enc = lua_encodepointer(L, ptr as usize);
93            let name = core::ffi::CStr::from_ptr(lua_l_typename(L, idx)).to_string_lossy();
94            lua_pushfstring_l(
95                L,
96                c"%s: 0x%016llx".as_ptr(),
97                format_args!("{}: 0x{:016x}", name, enc),
98            );
99        }
100    }
101
102    lua_tolstring(L, -1, len)
103}