comparison types.c @ 3:215c0c3b3609

misc: use JSON everywhere (scictl/sciwebd)
author David Demelier <markand@malikania.fr>
date Mon, 14 Jun 2021 22:08:24 +0200
parents
children 3051ef92173a
comparison
equal deleted inserted replaced
2:5fa3d2f479b2 3:215c0c3b3609
1 #include <assert.h>
2 #include <errno.h>
3
4 #include "types.h"
5
6 typedef json_t * (*packer)(const void *);
7 typedef int (*unpacker)(void *, json_t *);
8
9 static inline json_t *
10 job_packer(const struct job *job)
11 {
12 return json_pack("{si si ss}",
13 "id", job->id,
14 "project_id", job->project_id,
15 "tag", job->tag
16 );
17 }
18
19 static inline int
20 job_unpacker(struct job *job, json_t *doc)
21 {
22 return json_unpack(doc, "{si si ss}",
23 "id", &job->id,
24 "project_id", &job->project_id,
25 "tag", &job->tag
26 );
27 }
28
29 static inline json_t *
30 jobresult_packer(const struct jobresult *res)
31 {
32 return json_pack("{si si si si ss}",
33 "id", res->id,
34 "job_id", res->job_id,
35 "worker_id", res->worker_id,
36 "exitcode", res->exitcode,
37 "log", res->log
38 );
39 }
40
41 static inline int
42 jobresult_unpacker(struct jobresult *res, json_t *doc)
43 {
44 return json_unpack(doc, "{si si si si ss}",
45 "id", &res->id,
46 "job_id", &res->job_id,
47 "worker_id", &res->worker_id,
48 "exitcode", &res->exitcode,
49 "log", &res->log
50 );
51 }
52
53 static inline json_t *
54 worker_packer(const struct worker *w)
55 {
56 return json_pack("{si ss ss}",
57 "id", w->id,
58 "name", w->name,
59 "desc", w->desc
60 );
61 }
62
63 static inline int
64 worker_unpacker(struct worker *w, json_t *doc)
65 {
66 return json_unpack(doc, "{si ss ss}",
67 "id", &w->id,
68 "name", &w->name,
69 "desc", &w->desc
70 );
71 }
72
73 static inline json_t *
74 project_packer(struct project *p)
75 {
76 return json_pack("{si ss ss ss ss}",
77 "id", p->id,
78 "name", p->name,
79 "desc", p->desc,
80 "url", p->url,
81 "script", p->script
82 );
83 }
84
85 static inline int
86 project_unpacker(struct project *p, json_t *doc)
87 {
88 return json_unpack(doc, "{si ss ss ss ss}",
89 "id", &p->id,
90 "name", &p->name,
91 "desc", &p->desc,
92 "url", &p->url,
93 "script", &p->script
94 );
95 }
96
97 static json_t *
98 to(const void *array, size_t arraysz, size_t width, packer fn)
99 {
100 json_t *doc;
101
102 if (arraysz == 1)
103 doc = fn(array);
104 else {
105 doc = json_array();
106
107 for (size_t i = 0; i < arraysz; ++i)
108 json_array_append(doc, fn((char *)array + (i * width)));
109 }
110
111 return doc;
112 }
113
114 static ssize_t
115 from(void *array, size_t arraysz, size_t width, json_t *doc, unpacker fn)
116 {
117 json_t *val;
118 size_t i, tot = 0;
119
120 if (json_is_array(doc)) {
121 json_array_foreach(doc, i, val) {
122 if (tot >= arraysz)
123 return errno = ERANGE, -1;
124 if (fn((char *)array + (tot++ * width), val) < 0)
125 return errno = EILSEQ, -1;
126 }
127 } else if (json_is_object(doc)) {
128 tot = 1;
129
130 if (fn(array, doc) < 0)
131 return errno = EILSEQ, -1;
132 } else
133 return errno = EINVAL, -1;
134
135 return tot;
136 }
137
138 json_t *
139 job_to(const struct job *jobs, size_t jobsz)
140 {
141 assert(jobs);
142
143 return to(jobs, jobsz, sizeof (*jobs), (packer)job_packer);
144 }
145
146 ssize_t
147 job_from(struct job *jobs, size_t jobsz, json_t *doc)
148 {
149 assert(jobs);
150 assert(doc);
151
152 return from(jobs, jobsz, sizeof (*jobs), doc, (unpacker)job_unpacker);
153 }
154
155 json_t *
156 jobresult_to(const struct jobresult *res, size_t resz)
157 {
158 assert(res);
159
160 return to(res, resz, sizeof (*res), (packer)jobresult_packer);
161 }
162
163 ssize_t
164 jobresult_from(struct jobresult *res, size_t resz, json_t *doc)
165 {
166 assert(res);
167 assert(doc);
168
169 return from(res, resz, sizeof (*res), doc, (unpacker)jobresult_unpacker);
170 }
171
172 json_t *
173 worker_to(const struct worker *w, size_t wsz)
174 {
175 assert(w);
176
177 return to(w, wsz, sizeof (*w), (packer)worker_packer);
178 }
179
180 ssize_t
181 worker_from(struct worker *w, size_t wsz, json_t *doc)
182 {
183 assert(w);
184 assert(doc);
185
186 return from(w, wsz, sizeof (*w), doc, (unpacker)worker_unpacker);
187 }
188
189 json_t *
190 project_to(const struct project *proj, size_t projsz)
191 {
192 assert(proj);
193
194 return to(proj, projsz, sizeof (*proj), (packer)project_packer);
195 }
196
197 ssize_t
198 project_from(struct project *proj, size_t projsz, json_t *doc)
199 {
200 assert(proj);
201 assert(doc);
202
203 return from(proj, projsz, sizeof (*proj), doc, (unpacker)project_unpacker);
204 }