Skip to content

Commit 0452a8c

Browse files
Add an explicit JSONValue.opEquals method to fix taggedalgebraic support
The original `JSONValue` implementation relied on `alias payload this` for equality comparisons. This breaks with taggedalgebraic >= 0.11.0, with some of the failure cases emerging for all DMD versions, and others only for DMD >= 2.086.0. The former breakages seem to be related to changes in the implementation of `TaggedAlgebraic.opEquals`, while the cases that emerge only for DMD >= 2.086.0 appear to be related to a breaking change to prefer generated struct `opEquals` over aliased `opEquals`: https://dlang.org/changelog/2.086.0.html#alias_this_opEquals The aliased `opEquals` also fails in a number of array comparison cases, regardless of taggedalgebraic or compiler version. This patch fixes all these issues by implementing an explicit `opEquals` method. As with the previous implementation this relies only on payload and not on location, which appears to be in keeping with the rest of the library. We need to special case when `null` input is provided, as this could be ambiguous as to which `PayloadUnion` entry to compare to. Similarly, we special-case comparison of `JSONValue` to `JSONValue` in order to ensure that comparison is correctly based on their respective payloads. In all other cases, a direct comparison of input to payload appears sufficient. Fixes #44 (*). Fixes #48. (* Proof that the DMD >= 2.086.0 issues are fixed should be visible via the `dmd-beta` CI build, which should now pass.)
1 parent fc171c0 commit 0452a8c

1 file changed

Lines changed: 30 additions & 9 deletions

File tree

source/stdx/data/json/value.d

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,30 @@ struct JSONValue
9999
* Use `.hasType!T` or `.typeID` for that purpose.
100100
*/
101101
ref inout(T) get(T)() inout { return .get!T(payload); }
102+
103+
/**
104+
* Enables equality comparisons.
105+
*
106+
* Note that the location is considered token metadata and thus does not
107+
* affect the comparison.
108+
*/
109+
bool opEquals(T)(auto ref inout(T) other) inout
110+
{
111+
import std.traits : Unqual;
112+
113+
static if (is(Unqual!T == typeof(null)))
114+
{
115+
return this.isNull;
116+
}
117+
else static if (is(Unqual!T == JSONValue))
118+
{
119+
return this.payload == other.payload;
120+
}
121+
else
122+
{
123+
return this.payload == other;
124+
}
125+
}
102126
}
103127

104128
/// Shows the basic construction and operations on JSON values.
@@ -149,9 +173,8 @@ unittest
149173
assert(longval == 56.0);
150174
assert(longval == longval);
151175

152-
// FIXME: commented out test fails with taggedalgebraic v0.11.x
153176
assert(intval + longval == 78);
154-
// assert(intval + longval == intval + longval);
177+
assert(intval + longval == intval + longval);
155178

156179
JSONValue floatval = 32.0f;
157180
assert(floatval.hasType!double());
@@ -164,28 +187,26 @@ unittest
164187
assert(doubleval == 63.5);
165188
assert(doubleval == doubleval);
166189

167-
// FIXME: commented out tests fail with taggedalgebraic v0.11.x
168190
assert(floatval + doubleval == 95.5);
169-
// assert(floatval + doubleval == floatval + doubleval);
191+
assert(floatval + doubleval == floatval + doubleval);
170192
assert(intval + longval + floatval + doubleval == 173.5);
171-
// assert(intval + longval + floatval + doubleval ==
172-
// intval + longval + floatval + doubleval);
193+
assert(intval + longval + floatval + doubleval ==
194+
intval + longval + floatval + doubleval);
173195

174196
JSONValue strval = "Hello!";
175197
assert(strval.hasType!string());
176198
assert(strval == "Hello!");
177199
assert(strval == strval);
178200

179-
// FIXME: commented out tests fail <https://github.com/dlang-community/std_data_json/issues/48>
180201
auto arrval = JSONValue([floatval, doubleval]);
181202
assert(arrval.hasType!(JSONValue[])());
182-
// assert(arrval == [floatval, doubleval]);
203+
assert(arrval == [floatval, doubleval]);
183204
assert(arrval == [32.0, 63.5]);
184205
assert(arrval[0] == floatval);
185206
assert(arrval[0] == 32.0);
186207
assert(arrval[1] == doubleval);
187208
assert(arrval[1] == 63.5);
188-
// assert(arrval == arrval);
209+
assert(arrval == arrval);
189210

190211
auto objval = JSONValue(["f": floatval, "d": doubleval]);
191212
assert(objval.hasType!(JSONValue[string])());

0 commit comments

Comments
 (0)