mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-08 16:18:35 +02:00
lua: api: bind json-utils functions
This commit is contained in:
parent
89ac416e99
commit
fbecc50319
4 changed files with 236 additions and 0 deletions
|
|
@ -1713,6 +1713,86 @@ static const luaL_Reg conf_methods[] = {
|
|||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/* JsonUtils */
|
||||
|
||||
static gboolean
|
||||
json_utils_match_rules_cb (gpointer data, const gchar * action,
|
||||
WpSpaJson * value, GError ** error)
|
||||
{
|
||||
lua_State *L = data;
|
||||
g_autoptr (GError) pcall_err = NULL;
|
||||
gboolean ret = TRUE;
|
||||
int top = lua_gettop (L);
|
||||
|
||||
/* this callback is called within the context of json_utils_match_rules()
|
||||
* and the Lua callback function is at the top of the stack at this point */
|
||||
|
||||
/* re-push the function because lua_call pops it; then, push arguments */
|
||||
lua_pushvalue (L, -1);
|
||||
lua_pushstring (L, action);
|
||||
wplua_pushboxed (L, WP_TYPE_SPA_JSON, wp_spa_json_ref (value));
|
||||
|
||||
lua_call (L, 2, 2);
|
||||
|
||||
ret = lua_toboolean (L, -2);
|
||||
if (!ret) {
|
||||
g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
|
||||
"%s", lua_tostring (L, -1));
|
||||
}
|
||||
|
||||
lua_settop (L, top);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
json_utils_match_rules (lua_State *L)
|
||||
{
|
||||
g_autoptr (WpProperties) properties = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
WpSpaJson *json;
|
||||
gboolean res;
|
||||
|
||||
json = wplua_checkboxed (L, 1, WP_TYPE_SPA_JSON);
|
||||
luaL_checktype (L, 2, LUA_TTABLE);
|
||||
luaL_checktype (L, 3, LUA_TFUNCTION);
|
||||
|
||||
properties = wplua_table_to_properties (L, 2);
|
||||
|
||||
res = wp_json_utils_match_rules (json, properties, json_utils_match_rules_cb,
|
||||
L, &error);
|
||||
|
||||
lua_pushboolean (L, res);
|
||||
if (error)
|
||||
lua_pushstring (L, error->message);
|
||||
else
|
||||
lua_pushnil (L);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int
|
||||
json_utils_match_rules_update_properties (lua_State *L)
|
||||
{
|
||||
g_autoptr (WpProperties) properties = NULL;
|
||||
WpSpaJson *json;
|
||||
int count;
|
||||
|
||||
json = wplua_checkboxed (L, 1, WP_TYPE_SPA_JSON);
|
||||
luaL_checktype (L, 2, LUA_TTABLE);
|
||||
properties = wplua_table_to_properties (L, 2);
|
||||
|
||||
count = wp_json_utils_match_rules_update_properties (json, properties);
|
||||
|
||||
lua_pushinteger (L, count);
|
||||
wplua_properties_to_table (L, properties);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static const luaL_Reg json_utils_funcs[] = {
|
||||
{ "match_rules", json_utils_match_rules },
|
||||
{ "match_rules_update_properties", json_utils_match_rules_update_properties },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/* WpSettings */
|
||||
|
||||
static int
|
||||
|
|
@ -2390,6 +2470,9 @@ wp_lua_scripting_api_init (lua_State *L)
|
|||
luaL_newlib (L, conf_methods);
|
||||
lua_setglobal (L, "WpConf");
|
||||
|
||||
luaL_newlib (L, json_utils_funcs);
|
||||
lua_setglobal (L, "JsonUtils");
|
||||
|
||||
luaL_newlib (L, settings_methods);
|
||||
lua_setglobal (L, "WpSettings");
|
||||
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ SANDBOX_EXPORT = {
|
|||
ImplMetadata = WpImplMetadata_new,
|
||||
Settings = WpSettings,
|
||||
Conf = WpConf,
|
||||
JsonUtils = JsonUtils,
|
||||
SimpleEventHook = WpSimpleEventHook_new,
|
||||
AsyncEventHook = WpAsyncEventHook_new,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@ test(
|
|||
args: ['lua-api-tests', 'json.lua'],
|
||||
env: common_env,
|
||||
)
|
||||
test(
|
||||
'test-lua-json-utils',
|
||||
script_tester,
|
||||
args: ['lua-api-tests', 'json-utils.lua'],
|
||||
env: common_env,
|
||||
)
|
||||
test(
|
||||
'test-lua-monitor-rules',
|
||||
script_tester,
|
||||
|
|
|
|||
146
tests/wplua/scripts/json-utils.lua
Normal file
146
tests/wplua/scripts/json-utils.lua
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
rules_json_str = [[
|
||||
[
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
device.name = "~alsa_card.*"
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
api.alsa.use-acp = true
|
||||
api.acp.auto-port = false
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
node.name = "alsa_output.0.my-alsa-device"
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
audio.rate = 96000
|
||||
node.description = "My ALSA Node"
|
||||
media.class = null
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]]
|
||||
|
||||
match_props = { ["device.name"] = "unmatched-device-name" }
|
||||
ret, ret_props = JsonUtils.match_rules_update_properties (Json.Raw (rules_json_str), match_props)
|
||||
assert (ret == 0)
|
||||
assert (ret_props["device.name"] == match_props["device.name"])
|
||||
|
||||
match_props = { ["device.name"] = "alsa_card_0.my-alsa-device" }
|
||||
ret, ret_props = JsonUtils.match_rules_update_properties (Json.Raw (rules_json_str), match_props)
|
||||
assert (ret == 2)
|
||||
assert (ret_props["device.name"] == "alsa_card_0.my-alsa-device")
|
||||
assert (ret_props["api.alsa.use-acp"] == "true")
|
||||
assert (ret_props["api.acp.auto-port"] == "false")
|
||||
|
||||
match_props = { ["node.name"] = "alsa_output.0.my-alsa-device" }
|
||||
ret, ret_props = JsonUtils.match_rules_update_properties (Json.Raw (rules_json_str), match_props)
|
||||
assert (ret == 2)
|
||||
assert (ret_props["node.name"] == "alsa_output.0.my-alsa-device")
|
||||
assert (ret_props["audio.rate"] == "96000")
|
||||
assert (ret_props["node.description"] == "My ALSA Node")
|
||||
assert (ret_props["media.class"] == nil)
|
||||
|
||||
match_props = {
|
||||
["node.name"] = "alsa_output.0.my-alsa-device",
|
||||
["media.class"] = "Audio/Sink",
|
||||
["audio.rate"] = "48000",
|
||||
["node.description"] = "Test",
|
||||
}
|
||||
ret, ret_props = JsonUtils.match_rules_update_properties (Json.Raw (rules_json_str), match_props)
|
||||
assert (ret == 3)
|
||||
assert (ret_props["node.name"] == "alsa_output.0.my-alsa-device")
|
||||
assert (ret_props["audio.rate"] == "96000")
|
||||
assert (ret_props["node.description"] == "My ALSA Node")
|
||||
assert (ret_props["media.class"] == nil)
|
||||
|
||||
rules_json_str = [[
|
||||
[
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
device.name = "~alsa_card.*"
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
api.acp.auto-port = false
|
||||
}
|
||||
set-answer = 42
|
||||
}
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
test.error = true
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
generate-error = "test.error is true"
|
||||
}
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
device.name = "alsa_card.1"
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
set-description = "My ALSA Device"
|
||||
}
|
||||
}
|
||||
]
|
||||
]]
|
||||
|
||||
function match_rules_callback (action, value)
|
||||
if action == "update-props" then
|
||||
local updates = value:parse ()
|
||||
for k,v in pairs (updates) do
|
||||
match_props[k] = tostring (v)
|
||||
end
|
||||
elseif action == "set-answer" then
|
||||
local v = value:parse ()
|
||||
match_props["answer.universe"] = tostring (v)
|
||||
elseif action == "generate-error" then
|
||||
local err = value:parse ()
|
||||
return false, tostring (err)
|
||||
elseif action == "set-description" then
|
||||
local str = value:parse ()
|
||||
match_props["device.description"] = tostring (str)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
match_props = {
|
||||
["device.name"] = "alsa_card.1",
|
||||
["test.error"] = "false",
|
||||
}
|
||||
ret, err = JsonUtils.match_rules (Json.Raw (rules_json_str), match_props, match_rules_callback)
|
||||
assert (ret == true)
|
||||
assert (err == nil)
|
||||
assert (match_props["device.name"] == "alsa_card.1")
|
||||
assert (match_props["api.acp.auto-port"] == "false")
|
||||
assert (match_props["answer.universe"] == "42")
|
||||
assert (match_props["device.description"] == "My ALSA Device")
|
||||
|
||||
match_props = {
|
||||
["device.name"] = "alsa_card.1",
|
||||
["test.error"] = "true",
|
||||
}
|
||||
ret, err = JsonUtils.match_rules (Json.Raw (rules_json_str), match_props, match_rules_callback)
|
||||
assert (ret == false)
|
||||
assert (err == "test.error is true")
|
||||
assert (match_props["device.name"] == "alsa_card.1")
|
||||
assert (match_props["api.acp.auto-port"] == "false")
|
||||
assert (match_props["answer.universe"] == "42")
|
||||
assert (match_props["device.description"] == nil)
|
||||
Loading…
Add table
Reference in a new issue