Skip to content

Commit ecb1737

Browse files
ShahanaFarooquirustyrussell
authored andcommitted
commando: add restrictions information in listrune command
1 parent 7ad04a9 commit ecb1737

File tree

1 file changed

+125
-3
lines changed

1 file changed

+125
-3
lines changed

plugins/commando.c

Lines changed: 125 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,76 @@ static bool usage_eq_id(const struct usage *u, u64 id)
7777
HTABLE_DEFINE_TYPE(struct usage, usage_id, id_hash, usage_eq_id, usage_table);
7878
static struct usage_table *usage_table;
7979

80+
/* The unique id is embedded with a special restriction with an empty field name */
81+
static bool is_unique_id(struct rune_restr **restrs, unsigned int index)
82+
{
83+
/* must be the first restriction */
84+
if (index != 0)
85+
return false;
86+
87+
/* Must be the only alternative */
88+
if (tal_count(restrs[index]->alterns) != 1)
89+
return false;
90+
91+
/* Must have an empty field name */
92+
return streq(restrs[index]->alterns[0]->fieldname, "");
93+
}
94+
95+
static char *rune_altern_to_english(const tal_t *ctx, const struct rune_altern *alt)
96+
{
97+
const char *cond_str;
98+
switch (alt->condition) {
99+
case RUNE_COND_IF_MISSING:
100+
return tal_strcat(ctx, alt->fieldname, " is missing");
101+
case RUNE_COND_EQUAL:
102+
cond_str = "equal to";
103+
break;
104+
case RUNE_COND_NOT_EQUAL:
105+
cond_str = "unequal to";
106+
break;
107+
case RUNE_COND_BEGINS:
108+
cond_str = "starts with";
109+
break;
110+
case RUNE_COND_ENDS:
111+
cond_str = "ends with";
112+
break;
113+
case RUNE_COND_CONTAINS:
114+
cond_str = "contains";
115+
break;
116+
case RUNE_COND_INT_LESS:
117+
cond_str = "<";
118+
break;
119+
case RUNE_COND_INT_GREATER:
120+
cond_str = ">";
121+
break;
122+
case RUNE_COND_LEXO_BEFORE:
123+
cond_str = "sorts before";
124+
break;
125+
case RUNE_COND_LEXO_AFTER:
126+
cond_str = "sorts after";
127+
break;
128+
case RUNE_COND_COMMENT:
129+
return tal_fmt(ctx, "comment: %s %s", alt->fieldname, alt->value);
130+
}
131+
return tal_fmt(ctx, "%s %s %s", alt->fieldname, cond_str, alt->value);
132+
}
133+
134+
static char *json_add_alternative(const tal_t *ctx,
135+
struct json_stream *js,
136+
const char *fieldname,
137+
struct rune_altern *alternative)
138+
{
139+
char *altern_english;
140+
altern_english = rune_altern_to_english(ctx, alternative);
141+
json_object_start(js, fieldname);
142+
json_add_string(js, "fieldname", alternative->fieldname);
143+
json_add_string(js, "value", alternative->value);
144+
json_add_stringn(js, "condition", (char *)&alternative->condition, 1);
145+
json_add_string(js, "english", altern_english);
146+
json_object_end(js);
147+
return altern_english;
148+
}
149+
80150
static bool is_rune_blacklisted(const struct rune *rune)
81151
{
82152
u64 uid;
@@ -1037,16 +1107,56 @@ static struct command_result *json_commando_rune(struct command *cmd,
10371107
return send_outreq(plugin, req);
10381108
}
10391109

1040-
static struct command_result *json_add_runestr(struct json_stream *js,
1110+
static void join_strings(char **base, const char *connector, char *append)
1111+
{
1112+
if (streq(*base, "")) {
1113+
*base = append;
1114+
} else {
1115+
tal_append_fmt(base, " %s %s", connector, append);
1116+
}
1117+
}
1118+
1119+
static struct command_result *json_add_rune(struct json_stream *js,
1120+
const struct rune *rune,
10411121
const char *rune_str,
10421122
size_t rune_strlen,
10431123
bool stored)
10441124
{
1125+
char *rune_english;
1126+
rune_english = "";
10451127
json_object_start(js, NULL);
10461128
json_add_stringn(js, "rune", rune_str, rune_strlen);
10471129
if (!stored) {
10481130
json_add_bool(js, "stored", false);
10491131
}
1132+
if (is_rune_blacklisted(rune)) {
1133+
json_add_bool(js, "blacklisted", true);
1134+
}
1135+
if (rune_is_derived(master_rune, rune)) {
1136+
json_add_bool(js, "our_rune", false);
1137+
}
1138+
json_add_string(js, "unique_id", rune->unique_id);
1139+
json_array_start(js, "restrictions");
1140+
for (size_t i = 0; i < tal_count(rune->restrs); i++) {
1141+
char *restr_english;
1142+
restr_english = "";
1143+
/* Already printed out the unique id */
1144+
if (is_unique_id(rune->restrs, i)) {
1145+
continue;
1146+
}
1147+
json_object_start(js, NULL);
1148+
json_array_start(js, "alternatives");
1149+
for (size_t j = 0; j < tal_count(rune->restrs[i]->alterns); j++) {
1150+
join_strings(&restr_english, "OR",
1151+
json_add_alternative(tmpctx, js, NULL, rune->restrs[i]->alterns[j]));
1152+
}
1153+
json_array_end(js);
1154+
json_add_string(js, "english", restr_english);
1155+
json_object_end(js);
1156+
join_strings(&rune_english, "AND", restr_english);
1157+
}
1158+
json_array_end(js);
1159+
json_add_string(js, "restrictions_as_english", rune_english);
10501160
json_object_end(js);
10511161
return NULL;
10521162
}
@@ -1072,14 +1182,26 @@ static struct command_result *listdatastore_done(struct command *cmd,
10721182

10731183
json_array_start(js, "runes");
10741184
json_for_each_arr(i, t, d) {
1185+
const struct rune *this_rune;
10751186
const jsmntok_t *s = json_get_member(buf, t, "string");
10761187
if (runestr != NULL && !json_tok_streq(buf, s, runestr))
10771188
continue;
1078-
json_add_runestr(js, buf + s->start, s->end - s->start, true);
1189+
if (rune) {
1190+
this_rune = rune;
1191+
} else {
1192+
this_rune = rune_from_base64n(tmpctx, buf + s->start, s->end - s->start);
1193+
if (this_rune == NULL) {
1194+
plugin_log(plugin, LOG_BROKEN,
1195+
"Invalid rune in datastore %.*s",
1196+
s->end - s->start, buf + s->start);
1197+
continue;
1198+
}
1199+
}
1200+
json_add_rune(js, this_rune, buf + s->start, s->end - s->start, true);
10791201
printed = true;
10801202
}
10811203
if (rune && !printed) {
1082-
json_add_runestr(js, runestr, strlen(runestr), false);
1204+
json_add_rune(js, rune, runestr, strlen(runestr), false);
10831205
}
10841206
json_array_end(js);
10851207
return command_finished(cmd, js);

0 commit comments

Comments
 (0)