1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use td_clua;
use td_clua::lua_State;
use LuaPush;
use LuaRead;
use LuaTable;
use std::collections::{HashMap, HashSet};
use std::hash::Hash;
fn push_iter<V, I>(lua: *mut lua_State, iterator: I) -> i32
where
V: LuaPush,
I: Iterator<Item = V>,
{
unsafe { td_clua::lua_newtable(lua) };
for (elem, index) in iterator.zip(1..) {
let size = elem.push_to_lua(lua);
match size {
0 => continue,
1 => {
let index = index as u32;
index.push_to_lua(lua);
unsafe { td_clua::lua_insert(lua, -2) }
unsafe { td_clua::lua_settable(lua, -3) }
}
2 => unsafe { td_clua::lua_settable(lua, -3) },
_ => unreachable!(),
}
}
1
}
fn push_rec_iter<V, I>(lua: *mut lua_State, iterator: I) -> i32
where
V: LuaPush,
I: Iterator<Item = V>,
{
let (nrec, _) = iterator.size_hint();
unsafe { td_clua::lua_createtable(lua, 0, nrec as i32) };
for elem in iterator {
let size = elem.push_to_lua(lua);
match size {
0 => continue,
2 => unsafe { td_clua::lua_settable(lua, -3) },
_ => unreachable!(),
}
}
1
}
impl<T> LuaPush for Vec<T>
where
T: LuaPush,
{
fn push_to_lua(self, lua: *mut lua_State) -> i32 {
push_iter(lua, self.into_iter())
}
}
impl<'a, T> LuaPush for &'a [T]
where
T: Clone + LuaPush,
{
fn push_to_lua(self, lua: *mut lua_State) -> i32 {
push_iter(lua, self.iter().map(|e| e.clone()))
}
}
impl<K, V> LuaPush for HashMap<K, V>
where
K: LuaPush + Eq + Hash,
V: LuaPush,
{
fn push_to_lua(self, lua: *mut lua_State) -> i32 {
push_rec_iter(lua, self.into_iter())
}
}
impl<K> LuaPush for HashSet<K>
where
K: LuaPush + Eq + Hash,
{
fn push_to_lua(self, lua: *mut lua_State) -> i32 {
use std::iter;
push_rec_iter(lua, self.into_iter().zip(iter::repeat(true)))
}
}
impl<T> LuaRead for Vec<T>
where
T: LuaRead,
{
fn lua_read_with_pop(lua: *mut lua_State, index: i32, _pop: i32) -> Option<Vec<T>> {
let mut lua_table: LuaTable =
unwrap_or!(LuaRead::lua_read_at_position(lua, index), return None);
let mut result = vec![];
let len = lua_table.table_len();
for i in 1..(len + 1) {
let val: T = unwrap_or!(lua_table.query(i), return None);
result.push(val);
}
Some(result)
}
}