From 6beff688d2684a67e03c223c31c549f0d8246167 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Sat, 22 Mar 2025 17:16:50 +0000 Subject: [PATCH] std.json: Add JSONValue.toHash Allows using JSON values in sets and map keys. --- std/json.d | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/std/json.d b/std/json.d index 7182f6ee8..360bda5a5 100644 --- a/std/json.d +++ b/std/json.d @@ -1070,6 +1070,41 @@ struct JSONValue } } + /// Calculate a numerical hash value for this value, + /// allowing `JSONValue` to be used in associative arrays. + hash_t toHash() const @nogc nothrow pure @trusted + { + final switch (type_tag) + { + case JSONType.integer: + return hashOf(store.integer); + case JSONType.uinteger: + return hashOf(store.uinteger); + case JSONType.float_: + return hashOf(store.floating); + case JSONType.string: + return hashOf(store.str); + case JSONType.object: + hash_t result = hashOf(type_tag); + if (!store.object.isOrdered) + foreach (ref pair; store.object.unordered.byKeyValue) + result ^= hashOf(pair.key, pair.value.toHash()); + else + foreach (ref pair; store.object.ordered) + result ^= hashOf(pair.key, pair.value.toHash()); + return result; + case JSONType.array: + hash_t result = hashOf(type_tag); + foreach (ref v; store.array) + result = hashOf(v, result); + return result; + case JSONType.true_: + case JSONType.false_: + case JSONType.null_: + return hashOf(type_tag); + } + } + /// @safe unittest { @@ -2748,3 +2783,15 @@ pure nothrow @safe unittest assert(app.data == s, app.data); } + +@safe unittest +{ + bool[JSONValue] aa; + aa[JSONValue("test")] = true; + assert(parseJSON(`"test"`) in aa); + assert(parseJSON(`"boo"`) !in aa); + + aa[JSONValue(int(5))] = true; + assert(JSONValue(int(5)) in aa); + assert(JSONValue(uint(5)) in aa); +}