quinchs / EdgeDB.Net

C# edgedb client
Apache License 2.0
45 stars 3 forks source link

Add Client-side Custom Type Converter #31

Closed quinchs closed 1 year ago

quinchs commented 1 year ago

Summary

As demonstrated in discord, having a way to serialize/deserialize one type to another would be highly beneficial for wrapping or directly using types not supported by edgedb.

Type converters will be user-defined classes with 2 methods, Serialize and Deserialize. These classes will then be used in attributes on properties. Converters are executed during the object enumeration step[^1], tying into the ObjectBuilder class as part of the default conversion of objects[^2] and can be used to both serialize and deserialize properties.

Demo & Usage

In this demo, we want to store Discord snowflake ID's. With all popular dotnet Discord wrappers using the ulong type to represent these ID's, our classes should reflect this type, the problem is that there's no support for unsigned numbers in edgedb. Type converters can solve this issue by serializing/deserializing ulongs as strings.

Here's a sample schema, class, and type converter we could use for this:

module default {
  type User {
    required property user_id-> str;
  }
}
public class User
{
    [EdgeDBConverter(typeof(UlongConverter))]
    public ulong UserId { get; set; }
}
public class UlongConverter : EdgeDBConverter<ulong, string>
{
    public override string? Serialize(ulong value)
    {
        return value.ToString();
    }

    public override ulong Deserialize(string? value)
    {
        if(value is null)
            throw new ArgumentNullException(nameof(value));
        return ulong.Parse(value);
    }
}

[^1]: Object enumerator is part of the official release pull request. [^2]: Some objects are implicitly converted already, for example if your query returns an int32 and you specify an int64 as the resulting type, the library will implicitly convert the 32 bit int to a 64 bit int.