On 9/23/21 2:20 PM, james.p.leblanc wrote:
Dear D-ers,
In attempting to cast JSONValues that hold arrays to "native" array types,
I have hit some issues. Example code:
```d
import std.stdio;
import std.json;
void main(){
JSONValue jj;
jj["d"] = [ 1.234 ]; // a "dummy" double value
jj["ba"] = [ true, false, true]; // "ba" boolean array
Note that this creates a JSONValue array which *copies* the values of
the boolean array, converting them to JSONValue (which is what a
JSONValue array stores).
writeln("typeid(jj): ", typeid(jj), ", jj: ", jj );
// various things that I thought might work, but do NOT
auto z1 = cast(bool) jj["ba"]; // attempt #1
A JSONValue cannot be cast to a boolean (it does not provide the
appropriate opCast)
auto z2 = cast(bool[]) jj["ba"]; // attempt #2
auto z3 = cast(bool) jj["ba"].array; // attempt #3
These try to cast something that is not an array to an array or vice
versa. These are not supported unless the type itself has an `opCast`
overload.
auto z4 = cast(bool[]) jj["ba"].array; // attempt #4
Casting one array type to another is like pointing at the array that
represents the original type *as if* it were of the new type. No
translation is made, you are pointing at the same memory! The length is
adjusted based on the size of the original array element and the size of
the new one.
For instance:
```d
int[] arr = [1];
auto a2 = cast(ubyte[])arr;
assert(a2.length == 4);
assert(a2 == cast(ubyte[])([1, 0, 0, 0])); // assuming little endian
```
However, if I comment out the offending attempts (1, 2, and 3), then it
compiles, and can run ... but produces a result which I very much do NOT
understand:
typeid(jj): std.json.JSONValue, jj:
{"ba":[true,false,true],"d":[1.23399999999999999]}
typeid(z4): bool[], z4: [false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false,
true, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false,
false, false, false, false, true, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, true, false,
false, false, false, false, false, false]
This is an array of JSONValue, with each byte interpreted as if it were
a bool.
Hmmmm... is there a standard way to push these JSONValues into nice native
array types? (The real code is eventually going to be using traits and
mixins
... but I do not think this should pose additional problems).
How you really do this:
```d
import std.algorithm : map;
auto z5 = jj["ba"] // get the JSONValue that is at the key "ba"
.map!(v => v.get!bool) // map each value into a boolean
.array // create an array out of the results;
assert z5 == [true, false, true];
```
(warning, untested)
-Steve