How to parse a json node that contains children of different types?

Mathias LANG geod24 at gmail.com
Wed Jul 21 03:00:51 UTC 2021


On Tuesday, 20 July 2021 at 21:18:12 UTC, Bagomot wrote:
>
> But there is a problem with different types. I understand that 
> Object[] is not suitable here, but I don’t know how to do it.
>
> I ask you to help me with this.

IIUC, the `arguments` are command line arguments passed to a Java 
program, and some of those might be passed to the JVM ?

So you probably will end up with something like:
```
struct Arguments{
     JVMArgs jvm;
     ProgramArgs program;
}
```

Of course, the question is, what's `JVMArgs` ?

Now, as you noticed, you can't represent an array of unrelated 
types in D (which makes sense). So what you can do is create a 
common type for it, by using an `union`.

```
union JVMArg
{
     RuleValue ruleValue;
     string str;
     // Etc...
}
alias JVMArgs = JVMArg[];
```

However, \<YOUR-JSON-LIBRARY> might not support it directly, or 
might support it through its own type (you will need a tagged 
union, and not just a simple union, as you need to know the type 
that the library read).

But if you take a step back, I think you might find this solution 
is far from ideal.
Having worked on a JSON library myself, I can tell you they are 
all implemented with a tagged union. And converting a tagged 
union to a tagged union is no improvement.

Instead, I would recommend to just use the JSON directly. If you 
need to pass things around, you might want to deserialize it to a 
common format. For example, assuming your project is a process 
manager for Java program and you want to read a common set of 
arguments from a configuration file, you might want to just 
generate the strings:
```
auto myJSON = parseConfigFile("config.json");
string[] defaultJVMArgs = parseJVMArgs(myJSON);
auto processMonitor = new ProcessMonitor(defaultJVMArgs);
```

TL;DR: If you want to use loosely typed data in a strongly typed 
language, you need to come up with a common type. That common 
type is usually either a discriminated union (which a JSON object 
is, essentially) or something that is domain-specific.

Hope this helps. I had a quick look at asdf and couldn't see a 
support for tagged union, so you would probably need to provide 
your data structure with a `deserializeFromAsdf` method. If you 
want to do so, look into providing a wrapper to `SumType`, e.g.:

```
struct MyUnion (T...) {
     SumType!T data;
     alias data this;
     SerdeException deserializeFromAsdf(Asdf data) { /* Fill in 
the SumType */ }
```

But I would recommend just using the JSON object if you can.


More information about the Digitalmars-d-learn mailing list