1use neige_infra::LUA_RIDX_GLOBALS;
2
3use crate::{
4 state::LuaState,
5 value::{closure::RustFn, value::LuaValue},
6};
7
8use super::SetApi;
9
10pub trait PushApi {
11 fn push_nil(&mut self);
12 fn push_boolean(&mut self, b: bool);
13 fn push_integer(&mut self, i: i64);
14 fn push_number(&mut self, f: f64);
15 fn push_string(&mut self, s: &str);
16 fn push_rust_fn(&mut self, f: RustFn);
17 fn register(&mut self, name: &str, f: RustFn);
18 fn push_global_table(&mut self);
19 fn push_rust_closure(&mut self, f: RustFn, n: usize);
20}
21
22impl PushApi for LuaState {
23 fn push_nil(&mut self) {
24 self.stack_push(LuaValue::Nil)
25 }
26
27 fn push_boolean(&mut self, b: bool) {
28 self.stack_push(LuaValue::Boolean(b))
29 }
30
31 fn push_integer(&mut self, i: i64) {
32 self.stack_push(LuaValue::Integer(i))
33 }
34
35 fn push_number(&mut self, f: f64) {
36 self.stack_push(LuaValue::Number(f))
37 }
38
39 fn push_string(&mut self, s: &str) {
40 self.stack_push(LuaValue::Str(s.into()))
41 }
42
43 fn push_rust_fn(&mut self, f: RustFn) {
44 self.stack_push(LuaValue::new_rust_closure(f, 0))
45 }
46
47 fn register(&mut self, name: &str, f: RustFn) {
48 self.push_rust_fn(f);
49 self.set_global(name);
50 }
51
52 fn push_global_table(&mut self) {
53 let global = self.registry_get(&LuaValue::Integer(LUA_RIDX_GLOBALS));
54 self.stack_push(global)
55 }
56
57 fn push_rust_closure(&mut self, f: RustFn, mut n: usize) {
58 let closure = LuaValue::new_rust_closure(f, n);
59 while n > 0 {
60 let val = self.stack_pop();
61 if let LuaValue::Function(c) = &closure {
62 c.upvals.borrow_mut()[n - 1].set_val(val);
63 }
64 n -= 1
65 }
66 self.stack_push(closure)
67 }
68}