On Thursday, 2 June 2022 at 13:24:08 UTC, bauss wrote:
On Thursday, 2 June 2022 at 08:27:32 UTC, Antonio wrote:
JSON properties can be
- a value
- null
- absent
What's the standard way to define a
serialziable/deserializable structs supporting properties of
any of this 4 kinds?:
* int
* int | null
* int | absent
* int | null | absent
Whats the best library to manage this JSON requirements? (all
the 4 cases)?
Thanks
null and absent should be treated the same in the code, it's
only when serializing you should define one or the other, if
you need to have null values AND absent values then attributing
accordingly is the solution.
The main problem is when you need to use DTO struct that
"patches" data (not all the data) and absent vs null
discrimination is really mandatory.
A good approximation could be using SumTypes (what in Typescript
or Scala is named Union Types...), an incredible example of D
template power that could be used in Json
serialization/deserialization without the need of custom
properties attributes.
Here an example of how to define DTOs discriminating absent
(Undefined in javascrip) and null.
i.e.
```d
import std.sumtype: SumType, match;
import std.datetime.date: Date;
void main()
{
struct Undefined {}
struct Null {}
struct PersonPatchDTO {
SumType!(long) id;
SumType!(Undefined, string ) name;
SumType!(Undefined, string, string[]) surname;
SumType!(Undefined, Null, Date) birthday;
SumType!(Undefined, Null, long) partner_id;
}
auto patchPerson(PersonPatchDTO patch){
import std.stdio: writeln;
writeln( "Patching person in database ", patch );
}
// This should come from a JSON deserialization;
PersonPatchDTO patch = {
id:12334,
partner_id: Null()
};
patchPerson(patch);
}
```
Or the typical upset operation some people love to do
```d
void main(){
...
struct PersonUpsetDTO {
SumType!(Undefined, long) id;
SumType!(Undefined, string ) name;
SumType!(Undefined, string, string[]) surname;
SumType!(Undefined, Null, Date) birthday;
SumType!(Undefined, Null, long) partner_id;
}
auto upsetPerson(PersonUpsetDTO patch){
import std.stdio: writeln;
patch.id.match!(
(long l) => writeln("Updating person with id ", l),
(_) => writeln("Creating a new person")
);
}
...
}
```
D ha not "union types" native support, but SumType is a nice
substitution (with some overhead in generated code).
**Problems?**
- It is not the "standard" way expected by D Json
serializers/deserializers. It requires a custom one
- May be it's hard to inspect with debugger (I haven't tried yet)