From 9c5eb45d95da1b7b61d82f4bbca1af33b32a61b9 Mon Sep 17 00:00:00 2001 From: marisa Date: Wed, 21 Feb 2024 13:49:13 -0300 Subject: [PATCH] Better json management --- dub.sdl | 3 ++- source/ap/activity_stream.d | 30 ++++++++++++++++-------------- source/ap/actor.d | 31 ++++++++++++++----------------- source/util.d | 26 ++++++++++++++++---------- 4 files changed, 48 insertions(+), 42 deletions(-) diff --git a/dub.sdl b/dub.sdl index 6a487cd..12e5264 100644 --- a/dub.sdl +++ b/dub.sdl @@ -8,4 +8,5 @@ dependency "handy-httpd" version="~>8.2.0" dependency "ddbc" version="~>0.5.8" dependency "requests" version="~>2.1.3" dependency "hibernated" version="~>0.4.0" -subConfiguration "ddbc" "PGSQL" +// subConfiguration "ddbc" "SQLite" +// subConfiguration "ddbc" "PGSQL" diff --git a/source/ap/activity_stream.d b/source/ap/activity_stream.d index e7895b5..2d05850 100644 --- a/source/ap/activity_stream.d +++ b/source/ap/activity_stream.d @@ -9,10 +9,13 @@ import util; * https://www.w3.org/TR/activitypub/#obj +/ class ASObject { + // Required fields (for root objects) string context; /// Must be activitystream context string id; /// AP requirement for unique identifier string type; /// AP requirement for type of object + // Optional fields + JSONValue raw; /++ @@ -25,24 +28,23 @@ class ASObject { with (this) { const(JSONValue)* ascontext = "@context" in json; - if (ascontext == null) - throw new Exception("No context in ActivityStream Object"); + if (ascontext) { + switch ((*ascontext).type) { + case JSONType.ARRAY: + context = (*ascontext)[0].str; + break; - switch ((*ascontext).type) { - case JSONType.ARRAY: - context = (*ascontext)[0].str; - break; + case JSONType.STRING: + context = (*ascontext).str; + break; - case JSONType.STRING: - context = (*ascontext).str; - break; - - default: - throw new Exception("Invalid @context type for ActivityStream Object"); + default: + throw new Exception("Invalid @context type for ActivityStream Object"); + } } - id = json.requiredKey!"id".str; - type = json.requiredKey!"type".str; + optional(json, "id", id); + optional(json, "type", type); raw = json; } diff --git a/source/ap/actor.d b/source/ap/actor.d index 3dbef71..b072350 100644 --- a/source/ap/actor.d +++ b/source/ap/actor.d @@ -33,19 +33,16 @@ class Actor : ASObject { super(json); with (this) { - inbox = json.requiredKey!"inbox".str; - outbox = json.requiredKey!"outbox".str; - following = json.requiredKey!"following".str; - followers = json.requiredKey!"followers".str; + required(json, "inbox", inbox); + required(json, "outbox", outbox); + required(json, "following", following); + required(json, "followers", followers); - liked = json.checkKey!string("liked"); - streams = json.checkKey!string("streams"); - preferredUsername = json.checkKey!string("preferredUsername"); + optional(json, "liked", liked); + optional(json, "streams", streams); + optional(json, "preferredUsername", preferredUsername); - if (JSONValue* j = "endpoints" in json) - endpoints = ActorEndpoints.fromJson(*j); - else - endpoints = ActorEndpoints(); + endpoints = ActorEndpoints.fromJson(json.optional!JSONValue("endpoints")); raw = json; } @@ -64,12 +61,12 @@ struct ActorEndpoints { ActorEndpoints endpoints = ActorEndpoints(); with (endpoints) { - proxyUrl = json.checkKey!string("proxyUrl"); - oauthAuthorizationEndpoint = json.checkKey!string("oauthAuthorizationEndpoint"); - oauthTokenEndpoint = json.checkKey!string("oauthTokenEndpoint"); - provideClientKey = json.checkKey!string("provideClientKey"); - signClientKey = json.checkKey!string("signClientKey"); - sharedInbox = json.checkKey!string("sharedInbox"); + optional(json, "proxyUrl", proxyUrl); + optional(json, "oauthAuthorizationEndpoint", oauthAuthorizationEndpoint); + optional(json, "oauthTokenEndpoint", oauthTokenEndpoint); + optional(json, "provideClientKey", provideClientKey); + optional(json, "signClientKey", signClientKey); + optional(json, "sharedInbox", sharedInbox); } return endpoints; diff --git a/source/util.d b/source/util.d index 6612cd4..2aef033 100644 --- a/source/util.d +++ b/source/util.d @@ -3,18 +3,24 @@ module util; import std.format; import std.json; -JSONValue requiredKey(string key)(JSONValue val) { - const(JSONValue)* j = key in val; +void optional(T)(ref JSONValue val, string key, ref T receiver) { + const(JSONValue)* p = key in val; - if (j) - return *j; + if (p == null) + return; - throw new Exception(format("Key %s not found in json", key)); + static if (is(JSONValue == T)) + receiver = *p; + else + receiver = (*p).get!T; } -T checkKey(T)(JSONValue val, string key) { - if (JSONValue* j = key in val) - return (*j).get!T; - - return T.init; +T optional(T)(ref JSONValue val, string key) { + T t; + optional(val, key, t); + return t; +} + +void required(T)(ref JSONValue val, string key, ref T receiver) { + receiver = val[key].get!T; }