Skip to content

Commit c09cbf9

Browse files
committed
iop-openapi: add description for interface in tag
Declared a tag for every interface, and retrieve description from IOP comments in the module or in the interface. Change-Id: I5e925ab868c1fedcd2efd0ac257904c7450249de rip-it: 4d35664
1 parent 3ee5292 commit c09cbf9

File tree

5 files changed

+136
-11
lines changed

5 files changed

+136
-11
lines changed

iop-openapi.blk

Lines changed: 127 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,12 @@ typedef struct server_object_t {
220220
lstr_t description;
221221
} server_object_t;
222222

223+
typedef struct tag_object_t {
224+
lstr_t name;
225+
lstr_t description;
226+
} tag_object_t;
227+
qvector_t(tag, tag_object_t);
228+
223229
qm_kvec_t(whitelist, lstr_t, bool, qhash_lstr_hash, qhash_lstr_equal);
224230

225231
struct iop_openapi_t {
@@ -238,6 +244,8 @@ struct iop_openapi_t {
238244
/* security */
239245
lstr_t security;
240246

247+
qv_t(tag) tags;
248+
241249
/* whitelist of RPCs to expose, in the format "<iface_fullname>.<rpc>" */
242250
qm_t(whitelist) rpcs_whitelist;
243251

@@ -381,6 +389,61 @@ get_field_help(const iop_field_attrs_t * nullable attrs,
381389
}
382390
}
383391

392+
static void
393+
get_mod_iface_help(const iop_mod_t * nonnull mod,
394+
const iop_iface_alias_t * nonnull alias,
395+
const iop_help_t * nullable * nonnull help)
396+
{
397+
const iop_mod_iface_attrs_t *attrs;
398+
399+
*help = NULL;
400+
if (!TST_BIT(&mod->flags, IOP_MOD_EXTENDED) || !mod->ifaces_attrs) {
401+
return;
402+
}
403+
attrs = &mod->ifaces_attrs[alias - mod->ifaces];
404+
405+
for (int k = 0; k < attrs->attrs_len; k++) {
406+
const iop_mod_iface_attr_t *attr = &attrs->attrs[k];
407+
408+
switch (attr->type) {
409+
case IOP_MOD_IFACE_ATTR_HELP:
410+
*help = attr->args[0].v.p;
411+
return;
412+
case IOP_MOD_IFACE_ATTR_HELP_V2:
413+
*help = attr->args[0].v.p;
414+
return;
415+
default:
416+
break;
417+
}
418+
}
419+
}
420+
421+
static void
422+
get_iface_help(const iop_iface_t * nonnull iface,
423+
const iop_help_t * nullable * nonnull help)
424+
{
425+
*help = NULL;
426+
427+
if (!TST_BIT(&iface->flags, IOP_IFACE_HAS_ATTRS) || !iface->iface_attrs) {
428+
return;
429+
}
430+
431+
for (int k = 0; k < iface->iface_attrs->attrs_len; k++) {
432+
const iop_iface_attr_t *attr = &iface->iface_attrs->attrs[k];
433+
434+
switch (attr->type) {
435+
case IOP_IFACE_ATTR_HELP:
436+
*help = attr->args[0].v.p;
437+
return;
438+
case IOP_IFACE_ATTR_HELP_V2:
439+
*help = attr->args[0].v.p;
440+
return;
441+
default:
442+
break;
443+
}
444+
}
445+
}
446+
384447
/* }}} */
385448
/* {{{ Enums */
386449

@@ -1465,8 +1528,13 @@ t_iop_rpc_add(iop_openapi_t * nonnull oa, const iop_rpc_t * nonnull rpc,
14651528

14661529
static void
14671530
t_iop_iface_alias_add(iop_openapi_t * nonnull oa,
1531+
const iop_mod_t * nonnull mod,
14681532
const iop_iface_alias_t * nonnull alias)
14691533
{
1534+
tag_object_t *tag;
1535+
const iop_help_t *help;
1536+
t_SB_1k(sb);
1537+
14701538
for (int j = 0; j < alias->iface->funs_len; j++) {
14711539
const iop_rpc_t *rpc = &alias->iface->funs[j];
14721540
const unsigned rpc_flags = rpc->flags;
@@ -1496,13 +1564,34 @@ t_iop_iface_alias_add(iop_openapi_t * nonnull oa,
14961564
}
14971565
}
14981566
}
1567+
1568+
/* add a tag for the iface */
1569+
tag = qv_growlen0(&oa->tags, 1);
1570+
tag->name = alias->name;
1571+
1572+
/* Get description from both the iface alias in the module, and the iface
1573+
* itself.
1574+
*/
1575+
get_mod_iface_help(mod, alias, &help);
1576+
if (help) {
1577+
sb_add_lstr(&sb, t_iop_help_to_string(help, false));
1578+
}
1579+
1580+
get_iface_help(alias->iface, &help);
1581+
if (help) {
1582+
if (sb.len > 0) {
1583+
sb_adds(&sb, "\n\n");
1584+
}
1585+
sb_add_lstr(&sb, t_iop_help_to_string(help, false));
1586+
}
1587+
tag->description = sb.len > 0 ? LSTR_SB_V(&sb) : LSTR_NULL_V;
14991588
}
15001589

15011590
static void
15021591
t_iop_mod_add(iop_openapi_t * nonnull oa, const iop_mod_t * nonnull mod)
15031592
{
15041593
for (int i = 0; i < mod->ifaces_len; i++) {
1505-
t_iop_iface_alias_add(oa, &mod->ifaces[i]);
1594+
t_iop_iface_alias_add(oa, mod, &mod->ifaces[i]);
15061595
}
15071596
}
15081597

@@ -1607,6 +1696,25 @@ static void t_server_object_to_yaml(const server_object_t * nonnull obj,
16071696
}
16081697
}
16091698

1699+
/* }}} */
1700+
/* {{{ Tag object */
1701+
1702+
static void t_tag_object_to_yaml(const tag_object_t * nonnull obj,
1703+
yaml_data_t * nonnull out)
1704+
{
1705+
yaml_data_t data;
1706+
1707+
t_yaml_data_new_obj(out, 2);
1708+
1709+
yaml_data_set_string(&data, obj->name);
1710+
yaml_obj_add_field(out, LSTR("name"), data);
1711+
1712+
if (obj->description.s) {
1713+
yaml_data_set_string(&data, obj->description);
1714+
yaml_obj_add_field(out, LSTR("description"), data);
1715+
}
1716+
}
1717+
16101718
/* }}} */
16111719
/* {{{ Public API */
16121720

@@ -1619,11 +1727,13 @@ iop_openapi_t *t_new_iop_openapi(const lstr_t title, const lstr_t version,
16191727
oa->info.version = t_lstr_dup(version);
16201728
oa->module = module;
16211729

1622-
oa->server.route = t_lstr_dup(route);
1730+
t_qv_init(&oa->paths, 0);
16231731

16241732
t_components_object_init(&oa->components);
16251733

1626-
t_qv_init(&oa->paths, 0);
1734+
oa->server.route = t_lstr_dup(route);
1735+
1736+
t_qv_init(&oa->tags, 0);
16271737

16281738
t_qm_init(whitelist, &oa->rpcs_whitelist, 0);
16291739

@@ -1683,6 +1793,7 @@ int t_iop_openapi_to_yaml(iop_openapi_t *openapi, yaml_data_t *out,
16831793
sb_t *err)
16841794
{
16851795
yaml_data_t data;
1796+
yaml_data_t seq;
16861797
bool has_unused_whitelist = false;
16871798

16881799
if (openapi->module) {
@@ -1712,14 +1823,10 @@ int t_iop_openapi_to_yaml(iop_openapi_t *openapi, yaml_data_t *out,
17121823
t_info_object_to_yaml(&openapi->info, &data);
17131824
yaml_obj_add_field(out, LSTR("info"), data);
17141825

1715-
{
1716-
yaml_data_t seq;
1717-
1718-
t_yaml_data_new_seq(&seq, 1);
1719-
t_server_object_to_yaml(&openapi->server, &data);
1720-
yaml_seq_add_data(&seq, data);
1721-
yaml_obj_add_field(out, LSTR("servers"), seq);
1722-
}
1826+
t_yaml_data_new_seq(&seq, 1);
1827+
t_server_object_to_yaml(&openapi->server, &data);
1828+
yaml_seq_add_data(&seq, data);
1829+
yaml_obj_add_field(out, LSTR("servers"), seq);
17231830

17241831
t_paths_to_yaml(&openapi->paths, &data);
17251832
yaml_obj_add_field(out, LSTR("paths"), data);
@@ -1742,6 +1849,15 @@ int t_iop_openapi_to_yaml(iop_openapi_t *openapi, yaml_data_t *out,
17421849
yaml_obj_add_field(out, LSTR("security"), array);
17431850
}
17441851

1852+
if (openapi->tags.len > 0) {
1853+
t_yaml_data_new_seq(&seq, openapi->tags.len);
1854+
tab_for_each_ptr(tag, &openapi->tags) {
1855+
t_tag_object_to_yaml(tag, &data);
1856+
yaml_seq_add_data(&seq, data);
1857+
}
1858+
yaml_obj_add_field(out, LSTR("tags"), seq);
1859+
}
1860+
17451861
return 0;
17461862
}
17471863

test-data/openapi/dox.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,3 +451,6 @@ components:
451451
description: It is a \p comment for \ref a
452452
minimum: -2147483648
453453
maximum: 2147483647
454+
tags:
455+
- name: iface
456+
description: "comment for MyModule.iface\n\ncomment for MyIface"

test-data/openapi/iface_a.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,3 +385,5 @@ paths:
385385
text/html:
386386
schema:
387387
type: string
388+
tags:
389+
- name: a

test-data/openapi/iface_a_filtered.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ components:
3232
schemas:
3333
Void:
3434
type: object
35+
tags:
36+
- name: a

test-data/openapi/iface_t.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,5 @@ components:
5050
format: int32
5151
minimum: -2147483648
5252
maximum: 2147483647
53+
tags:
54+
- name: iface

0 commit comments

Comments
 (0)