int | missing | absent

Antonio antonio at abrevia.net
Tue Jun 21 21:06:21 UTC 2022


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)


More information about the Digitalmars-d-learn mailing list