teacher-tools/api/source/data_utils.d

58 lines
1.7 KiB
D

module data_utils;
import handy_httpd;
import asdf;
public import handy_httpd.components.optional;
/**
* Reads a JSON payload into a type T. Throws an `HttpStatusException` if
* the data cannot be read or converted to the given type, with a 400 BAD
* REQUEST status.
* Params:
* ctx = The request context to read from.
* Returns: The data that was read.
*/
T readJsonPayload(T)(ref HttpRequestContext ctx) {
try {
string requestBody = ctx.request.readBodyAsString();
return deserialize!T(requestBody);
} catch (SerdeException e) {
import slf4d;
warnF!"Failed to read JSON payload: %s"(e.msg);
throw new HttpStatusException(HttpStatus.BAD_REQUEST);
}
}
/**
* Writes data of type T to a JSON response body. Throws an `HttpStatusException`
* with status 501 INTERNAL SERVER ERROR if serialization fails.
* Params:
* ctx = The request context to write to.
* data = The data to write.
*/
void writeJsonBody(T)(ref HttpRequestContext ctx, in T data) {
import std.traits : isArray;
try {
static if (isArray!T) {
if (data.length == 0) {
ctx.response.writeBodyString("[]", "application/json");
return;
}
}
string jsonStr = serializeToJson(data);
ctx.response.writeBodyString(jsonStr, "application/json");
} catch (SerdeException e) {
throw new HttpStatusException(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
ulong getUnixTimestampMillis() {
import std.datetime;
SysTime now = Clock.currTime();
SysTime unixEpoch = SysTime(DateTime(1970, 1, 1), UTC());
Duration diff = now - unixEpoch;
return diff.total!"msecs";
}