1use lua::{Index, ToLua, FromLua, State, Type};
2use types::{LuaStackable, LuaGeneric};
3use context::Context;
4
5pub struct LuaTable {
7 index: Index
8}
9
10impl LuaTable {
11 pub fn new(i: Index) -> LuaTable {
13 LuaTable {
14 index: i
15 }
16 }
17
18 pub fn set_metatable(&self, context: &mut Context, meta: &LuaTable) {
22 context.get_state().push_value(meta.get_pos());
23 context.get_state().set_metatable(self.get_pos());
24 }
25
26 pub fn set(&self, context: &mut Context, key: &ToLua, value: &ToLua) {
31 key.to_lua(context.get_state());
32 value.to_lua(context.get_state());
33 context.get_state().set_table(self.get_pos());
34 }
35
36 pub fn set_raw(&self, context: &mut Context, key: &ToLua, value: &ToLua) {
40 key.to_lua(context.get_state());
41 value.to_lua(context.get_state());
42 context.get_state().raw_set(self.get_pos());
43 }
44
45 pub fn get(&self, context: &mut Context, key: &ToLua) -> LuaGeneric {
50 key.to_lua(context.get_state());
51 context.get_state().get_table(self.get_pos());
52 LuaGeneric::new(context.get_state().get_top())
53 }
54
55 pub fn get_raw(&self, context: &mut Context, key: &ToLua) -> LuaGeneric {
59 key.to_lua(context.get_state());
60 context.get_state().raw_get(self.get_pos());
61 LuaGeneric::new(context.get_state().get_top())
62 }
63
64 pub fn get_typed<T: FromLua>(&self, context: &mut Context, key: &ToLua) -> Option<T> {
66 key.to_lua(context.get_state());
67 context.get_state().get_table(self.get_pos());
68 let top = context.get_state().get_top();
69 let ret = context.get_state().to_type(top);
70 ret
71 }
72
73 pub fn len(&self, context: &mut Context) -> i64 {
83 context.get_state().len_direct(self.get_pos())
84 }
85
86 pub fn len_raw(&self, context: &mut Context) -> usize {
90 context.get_state().raw_len(self.get_pos())
91 }
92
93 pub fn iter_array<F>(&self, context: &mut Context, mut func: F)
98 where F: FnMut(Context, i64, LuaGeneric) {
99 for key in 1.. {
100 let mut new_context = context.push_context();
101 let value = self.get(&mut new_context, &key);
102 let t = value.type_of(&mut new_context);
103 match t {
104 Type::Nil => break,
105 _ => func(new_context, key, value)
106 };
107 }
108 }
109
110 pub fn append(&self, context: &mut Context, value: &ToLua) {
114 let length = self.len_raw(context);
115 self.set(context, &(length as i64+1), value);
116 }
117}
118
119impl LuaStackable for LuaTable {
120 fn get_pos(&self) -> Index {
121 self.index
122 }
123}
124
125impl ToLua for LuaTable {
126 fn to_lua(&self, state: &mut State) {
127 state.push_value(self.get_pos());
128 }
129}
130
131impl FromLua for LuaTable {
132 fn from_lua(state: &mut State, index: Index) -> Option<LuaTable> {
133 if state.is_table(index) {
134 Some(LuaTable::new(index))
135 } else {
136 None
137 }
138 }
139}