1use core::ffi::CStr;
4use lunka::prelude::*;
5
6const PRINT_CODE: &str = r#"print("Received arguments: ", ...)"#;
7
8const PRINT_CODE_LUA_NAME: &CStr = c"=<embedded>";
9
10trait Push<const N: usize> {
11 fn push_into(&self, thread: &LuaThread);
12}
13
14impl Push<1> for () {
15 fn push_into(&self, thread: &LuaThread) {
16 thread.push_nil();
17 }
18}
19
20impl Push<1> for LuaInteger {
21 fn push_into(&self, thread: &LuaThread) {
22 thread.push_integer(*self);
23 }
24}
25
26impl Push<1> for LuaNumber {
27 fn push_into(&self, thread: &LuaThread) {
28 thread.push_number(*self);
29 }
30}
31
32impl Push<1> for &str {
33 fn push_into(&self, thread: &LuaThread) {
34 thread.push_string(self.as_bytes());
35 }
36}
37
38impl<T: Push<1>, E: Push<1>> Push<2> for Result<T, E> {
39 fn push_into(&self, thread: &LuaThread) {
40 match self {
41 Self::Ok(t) => {
42 t.push_into(thread);
43 thread.push_nil()
44 }
45 Self::Err(e) => {
46 thread.push_fail();
47 e.push_into(thread)
48 }
49 }
50 }
51}
52
53trait LuaThreadExt {
54 fn push<const N: usize>(&self, what: impl Push<N>);
55}
56
57impl LuaThreadExt for LuaThread {
58 fn push<const N: usize>(&self, what: impl Push<N>) {
59 what.push_into(self)
60 }
61}
62
63fn main() {
64 let mut lua = Lua::new();
65 lua.run_managed(|mut mg| mg.open_libs());
66
67 if !lua.load_string(PRINT_CODE.as_bytes(), PRINT_CODE_LUA_NAME).is_ok() {
68 panic!("couldn't load Lua chunk");
69 }
70
71 lua.push(4 as LuaInteger);
72 lua.push(3.1 as LuaNumber);
73 lua.push("how");
74
75 if !lua.run_managed(|mut mg| {
76 mg.restart_gc();
77 unsafe { mg.pcall(3, 0, 0) }
78 }).is_ok() {
79 let error_bytes = lua.to_string(-1);
80 panic!(
81 "error while running Lua chunk: {}",
82 error_bytes.map(String::from_utf8_lossy)
83 .unwrap_or(std::borrow::Cow::Borrowed("<no message>"))
84 );
85 }
86}