@@ -77,6 +77,76 @@ static bool usage_eq_id(const struct usage *u, u64 id)
7777HTABLE_DEFINE_TYPE (struct usage , usage_id , id_hash , usage_eq_id , usage_table );
7878static 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+
80150static 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