mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 13:25:43 +01:00
common/json_filter: routine to turn "filter" JSON into a filter.
Since the "struct command" is different from plugins and lightningd, we need an accessor for this to work (the plugin one is a dummy for now!). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
3c75770586
commit
508a170598
@ -15,6 +15,9 @@ struct command_result *command_fail(struct command *cmd, enum jsonrpc_errcode co
|
||||
const char *fmt, ...)
|
||||
PRINTF_FMT(3, 4) WARN_UNUSED_RESULT RETURNS_NONNULL;
|
||||
|
||||
/* Caller supplies this too: must provide this to reach into cmd */
|
||||
struct json_filter **command_filter_ptr(struct command *cmd);
|
||||
|
||||
/* Convenient wrapper for "paramname: msg: invalid token '.*%s'" */
|
||||
static inline struct command_result *
|
||||
command_fail_badparam(struct command *cmd,
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <assert.h>
|
||||
#include <ccan/strmap/strmap.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_filter.h>
|
||||
#include <common/utils.h>
|
||||
|
||||
@ -190,3 +191,61 @@ const char *json_filter_misused(const tal_t *ctx, const struct json_filter *f)
|
||||
return tal_steal(ctx, ret);
|
||||
}
|
||||
}
|
||||
|
||||
/* Recursively populate filter. NULL on success.
|
||||
*
|
||||
* Example for listtransactions to include output type, amount_msat,
|
||||
* {"transactions": [{"outputs": [{"amount_msat": true, "type": true}]}]}
|
||||
*/
|
||||
static struct command_result *
|
||||
build_filter(struct command *cmd,
|
||||
const char *name,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
struct json_filter *filter)
|
||||
{
|
||||
struct command_result *ret;
|
||||
size_t i;
|
||||
const jsmntok_t *t;
|
||||
struct json_filter *subf;
|
||||
|
||||
if (tok->type == JSMN_ARRAY) {
|
||||
if (tok->size != 1)
|
||||
return command_fail_badparam(cmd, name, buffer, tok,
|
||||
"Arrays can only have one element");
|
||||
subf = json_filter_subarr(filter);
|
||||
return build_filter(cmd, name, buffer, tok + 1, subf);
|
||||
}
|
||||
|
||||
json_for_each_obj(i, t, tok) {
|
||||
bool is_true;
|
||||
const jsmntok_t *val = t + 1;
|
||||
|
||||
if (t->type != JSMN_STRING)
|
||||
return command_fail_badparam(cmd, name, buffer, t,
|
||||
"expected string key");
|
||||
subf = json_filter_subobj(filter, buffer + t->start, t->end - t->start);
|
||||
if (val->type == JSMN_OBJECT || val->type == JSMN_ARRAY) {
|
||||
ret = build_filter(cmd, name, buffer, val, subf);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else if (!json_to_bool(buffer, val, &is_true) || !is_true)
|
||||
return command_fail_badparam(cmd, name, buffer, val, "value must be true");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct command_result *parse_filter(struct command *cmd,
|
||||
const char *name,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok)
|
||||
{
|
||||
struct json_filter **filter = command_filter_ptr(cmd);
|
||||
|
||||
if (tok->type != JSMN_OBJECT)
|
||||
return command_fail_badparam(cmd, name, buffer, tok,
|
||||
"Expected object");
|
||||
|
||||
*filter = json_filter_new(cmd);
|
||||
return build_filter(cmd, name, buffer, tok, *filter);
|
||||
}
|
||||
|
@ -5,8 +5,10 @@
|
||||
#define LIGHTNING_COMMON_JSON_FILTER_H
|
||||
#include "config.h"
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <common/json_parse_simple.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct command;
|
||||
struct json_filter;
|
||||
|
||||
/* Print this? */
|
||||
@ -31,4 +33,9 @@ struct json_filter *json_filter_subobj(struct json_filter *filter,
|
||||
size_t fieldnamelen);
|
||||
struct json_filter *json_filter_subarr(struct json_filter *filter);
|
||||
|
||||
/* Turn this "filter" field into cmd->filter and return NULL, or fail command */
|
||||
struct command_result *parse_filter(struct command *cmd,
|
||||
const char *name,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok);
|
||||
#endif /* LIGHTNING_COMMON_JSON_FILTER_H */
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_filter.h>
|
||||
#include <common/json_param.h>
|
||||
#include <common/memleak.h>
|
||||
#include <common/timeout.h>
|
||||
@ -493,6 +494,11 @@ struct command_result *command_fail(struct command *cmd, enum jsonrpc_errcode co
|
||||
return command_failed(cmd, r);
|
||||
}
|
||||
|
||||
struct json_filter **command_filter_ptr(struct command *cmd)
|
||||
{
|
||||
return &cmd->filter;
|
||||
}
|
||||
|
||||
struct command_result *command_still_pending(struct command *cmd)
|
||||
{
|
||||
notleak_with_children(cmd);
|
||||
@ -909,6 +915,7 @@ parse_request(struct json_connection *jcon, const jsmntok_t tok[])
|
||||
c->id_is_string = (id->type == JSMN_STRING);
|
||||
c->id = json_strdup(c, jcon->buffer, id);
|
||||
c->mode = CMD_NORMAL;
|
||||
c->filter = NULL;
|
||||
list_add_tail(&jcon->commands, &c->list);
|
||||
tal_add_destructor(c, destroy_command);
|
||||
|
||||
|
@ -41,6 +41,8 @@ struct command {
|
||||
enum command_mode mode;
|
||||
/* Have we started a json stream already? For debugging. */
|
||||
struct json_stream *json_stream;
|
||||
/* Optional output field filter. */
|
||||
struct json_filter *filter;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -132,6 +132,12 @@ struct command_result *command_done(void)
|
||||
return &complete;
|
||||
}
|
||||
|
||||
/* Don't ask for _filter, we will crash! */
|
||||
struct json_filter **command_filter_ptr(struct command *cmd)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ld_send(struct plugin *plugin, struct json_stream *stream)
|
||||
{
|
||||
struct jstream *jstr = tal(plugin, struct jstream);
|
||||
|
Loading…
Reference in New Issue
Block a user