Mercurial > sci
diff lib/apic.c @ 27:dae2de19ca5d
misc: switch to JSON everywhere
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 03 Aug 2022 15:18:09 +0200 |
parents | 34cbbd215ef7 |
children |
line wrap: on
line diff
--- a/lib/apic.c Tue Aug 02 13:24:13 2022 +0200 +++ b/lib/apic.c Wed Aug 03 15:18:09 2022 +0200 @@ -7,7 +7,6 @@ #include <curl/curl.h> #include "apic.h" -#include "types.h" #include "util.h" struct curlpack { @@ -16,13 +15,6 @@ struct curl_slist *headers; }; -struct converter { - void *data; - size_t datasz; - ssize_t (*unpack)(void *, size_t, json_t *); - json_t *(*pack)(const void *, size_t); -}; - struct apiconf apiconf = { .baseurl = "http://127.0.0.1" }; @@ -39,7 +31,7 @@ static inline char * create_url(const char *fmt, va_list args) { - static _Thread_local char ret[256]; + static _Thread_local char ret[1024]; char page[128]; va_list ap; @@ -93,14 +85,14 @@ return pack; } -static int +static json_t * perform(struct apic *req, const char *body, const char *fmt, va_list ap) { FILE *fp; char *response, *url; size_t responsesz; + json_t *doc = NULL; json_error_t error; - int ret = -1; struct curlpack curl; memset(req, 0, sizeof (*req)); @@ -119,10 +111,8 @@ if (req->status != 200) snprintf(req->error, sizeof (req->error), "HTTP returned %ld", req->status); - if (response[0] && !(req->doc = json_loads(response, 0, &error))) + if (response[0] && !(doc = json_loads(response, 0, &error))) snprintf(req->error, sizeof (req->error), "JSON parse error: %s", error.text); - else - ret = 0; } curl_easy_cleanup(curl.curl); @@ -130,112 +120,59 @@ free(response); - return ret; + return doc; } -static ssize_t -get(struct apic *req, const struct converter *cv, const char *fmt, ...) +static json_t * +get(struct apic *req, const char *fmt, ...) { va_list ap; - ssize_t ret; + json_t *ret; va_start(ap, fmt); ret = perform(req, NULL, fmt, ap); va_end(ap); - if (ret < 0) - return -1; - if (!req->doc || (!json_is_object(req->doc) && !json_is_array(req->doc))) - return snprintf(req->error, sizeof (req->error), "invalid JSON document received"), -1; - if ((ret = cv->unpack(cv->data, cv->datasz, req->doc)) < 0) - return snprintf(req->error, sizeof (req->error), "%s", strerror(errno)); + if (!ret || (!json_is_object(ret) && !json_is_array(ret))) + snprintf(req->error, sizeof (req->error), "invalid JSON document received"); return ret; } static int -create(struct apic *req, const struct converter *cv, const char *fmt, ...) +create(struct apic *req, json_t *doc, const char *fmt, ...) { va_list ap; - int ret; - json_t *doc; + json_t *ret; char *body; memset(req, 0, sizeof (*req)); - if (!(doc = cv->pack(cv->data, cv->datasz))) - return snprintf(req->error, sizeof (req->error), "%s", strerror(errno)); if (!(body = json_dumps(doc, JSON_COMPACT))) { json_decref(doc); - return snprintf(req->error, sizeof (req->error), "%s", strerror(errno)); + return snprintf(req->error, sizeof (req->error), "%s", strerror(errno)), -1; } va_start(ap, fmt); ret = perform(req, body, fmt, ap); va_end(ap); - json_decref(doc); + /* TODO: update id. */ + (void)ret; + free(body); - return ret; -} - -static json_t * -wrap_job_to(const void *data, size_t datasz) -{ - return job_to(data, datasz); -} - -static ssize_t -wrap_job_from(void *data, size_t datasz, json_t *doc) -{ - return job_from(data, datasz, doc); -} - -static json_t * -wrap_jobresult_to(const void *data, size_t datasz) -{ - return jobresult_to(data, datasz); + return 0; } -static ssize_t -wrap_project_from(void *data, size_t datasz, json_t *doc) -{ - return project_from(data, datasz, doc); -} - -static json_t * -wrap_project_to(const void *data, size_t datasz) -{ - return project_to(data, datasz); -} - -static ssize_t -wrap_worker_from(void *data, size_t datasz, json_t *doc) -{ - return worker_from(data, datasz, doc); -} - -static json_t * -wrap_worker_to(const void *data, size_t datasz) -{ - return worker_to(data, datasz); -} - -static ssize_t -wrap_jobresult_from(void *data, size_t datasz, json_t *doc) -{ - return jobresult_from(data, datasz, doc); -} - -int +json_t * apic_get(struct apic *req, const char *fmt, ...) { assert(req); assert(fmt); va_list ap; - int ret; + json_t *ret; va_start(ap, fmt); ret = perform(req, NULL, fmt, ap); @@ -244,14 +181,14 @@ return ret; } -int +json_t * apic_post(struct apic *req, const json_t *doc, const char *fmt, ...) { assert(req); assert(fmt); va_list ap; - int ret; + json_t *ret; char *body; if (!(body = json_dumps(doc, JSON_COMPACT))) @@ -267,167 +204,80 @@ } int -apic_job_add(struct apic *req, struct job *job) +apic_job_add(struct apic *req, json_t *job) { assert(req); assert(job); - const struct converter cv = { - .data = job, - .datasz = 1, - .pack = wrap_job_to, - .unpack = wrap_job_from - }; - - return create(req, &cv, "api/v1/jobs"); + return create(req, job, "api/v1/jobs"); } -ssize_t -apic_job_todo(struct apic *req, struct job *jobs, size_t jobsz, const char *worker_name) +json_t * +apic_job_todo(struct apic *req, const char *worker_name) { assert(req); - assert(jobs); + assert(worker_name); - struct converter cv = { - .data = jobs, - .datasz = jobsz, - .unpack = wrap_job_from - }; - - return get(req, &cv, "api/v1/todo/%s", worker_name); + return get(req, "api/v1/todo/%s", worker_name); } int -apic_jobresult_add(struct apic *req, struct jobresult *result) +apic_jobresult_add(struct apic *req, json_t *res) { assert(req); - assert(result); + assert(res); - struct converter cv = { - .data = result, - .datasz = 1, - .pack = wrap_jobresult_to, - .unpack = wrap_jobresult_from - }; - - return create(req, &cv, "api/v1/jobresults"); + return create(req, res, "api/v1/jobresults"); } int -apic_project_save(struct apic *req, struct project *project) +apic_project_save(struct apic *req, json_t *p) +{ + assert(req); + assert(p); + + return create(req, p, "api/v1/projects"); +} + +json_t * +apic_project_list(struct apic *req) { assert(req); - assert(project); + + return get(req, "api/v1/projects"); +} - struct converter cv = { - .data = project, - .datasz = 1, - .pack = wrap_project_to, - .unpack = wrap_project_from - }; +json_t * +apic_project_find(struct apic *req, const char *name) +{ + assert(req); + assert(name); - return create(req, &cv, "api/v1/projects"); + return get(req, "api/v1/projects/%s", name); } int -apic_project_update(struct apic *req, struct project *project) -{ - assert(req); - assert(project); - - struct converter cv = { - .data = project, - .datasz = 1, - .pack = wrap_project_to, - .unpack = wrap_project_from - }; - - return create(req, &cv, "api/v1/projects"); -} - -ssize_t -apic_project_list(struct apic *req, struct project *projects, size_t projectsz) -{ - assert(req); - assert(projects); - - struct converter cv = { - .data = projects, - .datasz = projectsz, - .unpack = wrap_project_from - }; - - return get(req, &cv, "api/v1/projects"); -} - -int -apic_project_find(struct apic *req, struct project *project, const char *name) -{ - assert(req); - assert(project); - - struct converter cv = { - .data = project, - .datasz = 1, - .unpack = wrap_project_from - }; - - return get(req, &cv, "api/v1/projects/%s", name); -} - -int -apic_worker_save(struct apic *req, struct worker *wk) +apic_worker_save(struct apic *req, json_t *wk) { assert(req); assert(wk); - struct converter cv = { - .data = wk, - .datasz = 1, - .pack = wrap_worker_to - }; - - return create(req, &cv, "api/v1/workers"); + return create(req, wk, "api/v1/workers"); } -ssize_t -apic_worker_list(struct apic *req, struct worker *wk, size_t wksz) -{ - assert(req); - assert(wk); - assert(wksz); - - struct converter cv = { - .data = wk, - .datasz = wksz, - .unpack = wrap_worker_from - }; - - return get(req, &cv, "api/v1/workers"); -} - -int -apic_worker_find(struct apic *req, struct worker *wk, const char *name) -{ - assert(req); - assert(wk); - - struct converter cv = { - .data = wk, - .datasz = 1, - .unpack = wrap_worker_from - }; - - return get(req, &cv, "api/v1/workers/%s", name); -} - -void -apic_finish(struct apic *req) +json_t * +apic_worker_list(struct apic *req) { assert(req); - if (req->doc) - json_decref(req->doc); + return get(req, "api/v1/workers"); +} - memset(req, 0, sizeof (*req)); +json_t * +apic_worker_find(struct apic *req, const char *name) +{ + assert(req); + assert(name); + + return get(req, "api/v1/workers/%s", name); }