haproxy-api-rs
haproxy-api-rs copied to clipboard
Getting proxies from core object fails due to use of special meta methods
The Core object contains methods for extracting proxies/frontends/backends but these do not seem to work. What happens is that these methods use the mlua Table.pairs() method on tables which return some AnyUserData which can't be converted to a LuaTable and so throws an error.
This happens because the underlying tables for these core fields aren't normal Lua tables and instead use custom meta methods to implement __pairs and provide dynamic results. The mlua pairs() method specifically does not use the __pairs meta method, so the data isn't normally accessible.
You can extract and cast these successfully to Proxy structs if you use the underlying __pairs implementation directly. I threw together a quick iterator using the actual __pairs metamethod since I couldn't find any way to use it via mlua, though I may be missing something.
pub(crate) struct Pairs<T> {
next: LuaFunction,
_phantom: PhantomData<T>,
}
impl<T> Pairs<T> {
pub(crate) fn from(tbl: &LuaTable) -> LuaResult<Self> {
Ok(Self {
next: tbl
.metatable()
.unwrap()
.get::<LuaFunction>("__pairs")
.unwrap()
.call::<LuaFunction>(tbl)
.unwrap(),
_phantom: PhantomData,
})
}
}
impl<T> Iterator for Pairs<T>
where
T: FromLuaMulti,
{
type Item = (LuaString, T);
fn next(&mut self) -> Option<Self::Item> {
self.next.call::<(LuaString, T)>(()).ok()
}
}
Using this allows you to iterate over the proxies/frontends/backends tables as intended and can also be used for the Servers inside of the proxy.servers tables which have the same issue and potentially other fields I haven't noticed yet.