Add lua::push for QJson types

This commit is contained in:
Mm2PL 2024-06-19 16:32:22 +02:00
parent 052dbd7d2c
commit 962b2c6c1d
No known key found for this signature in database
GPG key ID: 94AC9B80EFA15ED9
5 changed files with 120 additions and 0 deletions

View file

@ -15,6 +15,7 @@ extern "C" {
# include <lualib.h> # include <lualib.h>
} }
# include <QFileInfo> # include <QFileInfo>
# include <QJsonDocument>
# include <QLoggingCategory> # include <QLoggingCategory>
# include <QTextCodec> # include <QTextCodec>
# include <QUrl> # include <QUrl>
@ -209,6 +210,28 @@ int c2_later(lua_State *L)
return 0; return 0;
} }
int c2_json_load(lua_State *L)
{
lua::StackGuard guard(L, 0); // 1 in, 1 out
std::string str;
if (!lua::pop(L, &str))
{
return luaL_error(
L, "Cannot get json_data (only argument of c2.json_load, "
"expected a string)");
}
QJsonParseError err{};
auto doc = QJsonDocument::fromJson(QByteArray::fromStdString(str), &err);
if (err.error != QJsonParseError::NoError)
{
return luaL_error(L, "Failed to parse JSON data: %s",
err.errorString().toStdString().c_str());
}
lua::push(L, doc);
return 1;
}
int g_load(lua_State *L) int g_load(lua_State *L)
{ {
# ifdef NDEBUG # ifdef NDEBUG

View file

@ -121,6 +121,18 @@ int c2_log(lua_State *L);
*/ */
int c2_later(lua_State *L); int c2_later(lua_State *L);
/**
* @lua@alias AnyJSON integer|boolean|string|number|table
*/
/**
* Loads json data from a string into Lua tables.
*
* @lua@param json_data string Data you want to load
* @lua@return AnyJSON Deserialized data.
*/
int c2_json_load(lua_State *L);
// These ones are global // These ones are global
int g_load(lua_State *L); int g_load(lua_State *L);
int g_print(lua_State *L); int g_print(lua_State *L);

View file

@ -7,6 +7,8 @@
# include "controllers/plugins/api/ChannelRef.hpp" # include "controllers/plugins/api/ChannelRef.hpp"
# include "controllers/plugins/LuaAPI.hpp" # include "controllers/plugins/LuaAPI.hpp"
# include <cassert>
extern "C" { extern "C" {
# include <lauxlib.h> # include <lauxlib.h>
# include <lua.h> # include <lua.h>
@ -142,6 +144,12 @@ StackIdx push(lua_State *L, const int &b)
return lua_gettop(L); return lua_gettop(L);
} }
StackIdx push(lua_State *L, const double &n)
{
lua_pushnumber(L, n);
return lua_gettop(L);
}
StackIdx push(lua_State *L, const api::CompletionEvent &ev) StackIdx push(lua_State *L, const api::CompletionEvent &ev)
{ {
auto idx = pushEmptyTable(L, 4); auto idx = pushEmptyTable(L, 4);
@ -156,6 +164,76 @@ StackIdx push(lua_State *L, const api::CompletionEvent &ev)
return idx; return idx;
} }
StackIdx push(lua_State *L, const QJsonDocument &doc)
{
if (doc.isNull())
{
lua_pushnil(L);
return lua_gettop(L);
}
if (doc.isArray())
{
return push(L, doc.array());
}
if (doc.isObject())
{
return push(L, doc.object());
}
assert(false && "A QJsonDocument must be null, an array or an object");
return 0;
}
StackIdx push(lua_State *L, const QJsonArray &arr)
{
auto out = pushEmptyArray(L, arr.size());
int index = 1;
for (const auto &val : arr)
{
lua::push(L, val);
lua_seti(L, out, index);
index += 1;
}
return out;
}
StackIdx push(lua_State *L, const QJsonObject &obj)
{
auto out = pushEmptyTable(L, obj.size());
for (const auto &key : obj.keys())
{
const auto &value = obj.value(key);
lua::push(L, value);
lua_setfield(L, out, key.toStdString().c_str());
}
return out;
}
StackIdx push(lua_State *L, const QJsonValue &val)
{
switch (val.type())
{
case QJsonValue::Null:
lua_pushnil(L);
return lua_gettop(L);
case QJsonValue::Bool:
return push(L, val.toBool());
case QJsonValue::String:
return push(L, val.toString());
case QJsonValue::Array:
return push(L, val.toArray());
case QJsonValue::Object:
return push(L, val.toObject());
case QJsonValue::Double:
return push(L, val.toDouble());
case QJsonValue::Undefined:
assert(false && "Tried to push undefined/erroneous QJsonValue into "
"Lua, this is not allowed.");
default:
assert(false && "Malformed QJsonValue type. This never happens");
}
}
bool peek(lua_State *L, int *out, StackIdx idx) bool peek(lua_State *L, int *out, StackIdx idx)
{ {
StackGuard guard(L); StackGuard guard(L);

View file

@ -9,6 +9,7 @@ extern "C" {
# include <lualib.h> # include <lualib.h>
} }
# include <magic_enum/magic_enum.hpp> # include <magic_enum/magic_enum.hpp>
# include <QJsonDocument>
# include <QList> # include <QList>
# include <cassert> # include <cassert>
@ -67,7 +68,12 @@ StackIdx push(lua_State *L, const QString &str);
StackIdx push(lua_State *L, const std::string &str); StackIdx push(lua_State *L, const std::string &str);
StackIdx push(lua_State *L, const bool &b); StackIdx push(lua_State *L, const bool &b);
StackIdx push(lua_State *L, const int &b); StackIdx push(lua_State *L, const int &b);
StackIdx push(lua_State *L, const double &n);
StackIdx push(lua_State *L, const api::CompletionEvent &ev); StackIdx push(lua_State *L, const api::CompletionEvent &ev);
StackIdx push(lua_State *L, const QJsonDocument &doc);
StackIdx push(lua_State *L, const QJsonArray &arr);
StackIdx push(lua_State *L, const QJsonObject &obj);
StackIdx push(lua_State *L, const QJsonValue &val);
// returns OK? // returns OK?
bool peek(lua_State *L, int *out, StackIdx idx = -1); bool peek(lua_State *L, int *out, StackIdx idx = -1);

View file

@ -152,6 +152,7 @@ void PluginController::openLibrariesFor(lua_State *L, const PluginMeta &meta,
{"register_callback", lua::api::c2_register_callback}, {"register_callback", lua::api::c2_register_callback},
{"log", lua::api::c2_log}, {"log", lua::api::c2_log},
{"later", lua::api::c2_later}, {"later", lua::api::c2_later},
{"json_load", lua::api::c2_json_load},
{nullptr, nullptr}, {nullptr, nullptr},
}; };
lua_pushglobaltable(L); lua_pushglobaltable(L);