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);
 }