@@ -77,6 +77,76 @@ static bool usage_eq_id(const struct usage *u, u64 id)
77
77
HTABLE_DEFINE_TYPE (struct usage , usage_id , id_hash , usage_eq_id , usage_table );
78
78
static struct usage_table * usage_table ;
79
79
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
+
80
150
static bool is_rune_blacklisted (const struct rune * rune )
81
151
{
82
152
u64 uid ;
@@ -1037,16 +1107,56 @@ static struct command_result *json_commando_rune(struct command *cmd,
1037
1107
return send_outreq (plugin , req );
1038
1108
}
1039
1109
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 ,
1041
1121
const char * rune_str ,
1042
1122
size_t rune_strlen ,
1043
1123
bool stored )
1044
1124
{
1125
+ char * rune_english ;
1126
+ rune_english = "" ;
1045
1127
json_object_start (js , NULL );
1046
1128
json_add_stringn (js , "rune" , rune_str , rune_strlen );
1047
1129
if (!stored ) {
1048
1130
json_add_bool (js , "stored" , false);
1049
1131
}
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 );
1050
1160
json_object_end (js );
1051
1161
return NULL ;
1052
1162
}
@@ -1072,14 +1182,26 @@ static struct command_result *listdatastore_done(struct command *cmd,
1072
1182
1073
1183
json_array_start (js , "runes" );
1074
1184
json_for_each_arr (i , t , d ) {
1185
+ const struct rune * this_rune ;
1075
1186
const jsmntok_t * s = json_get_member (buf , t , "string" );
1076
1187
if (runestr != NULL && !json_tok_streq (buf , s , runestr ))
1077
1188
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);
1079
1201
printed = true;
1080
1202
}
1081
1203
if (rune && !printed ) {
1082
- json_add_runestr (js , runestr , strlen (runestr ), false);
1204
+ json_add_rune (js , rune , runestr , strlen (runestr ), false);
1083
1205
}
1084
1206
json_array_end (js );
1085
1207
return command_finished (cmd , js );
0 commit comments