RejectedSoftware Forums

Sign up

Serialization of custom non-extensible structs (e.g. UUID)

Hi,

I was wondering if it is possible to have vibe.d (de)serialize custom types that cannot be reasonable extended by providing toRepresentation/fromRepresentation, e.g. UUID struct from std.uuid.

After checking the isCustomSerializable trait, I tried to use this code:

string toRepresentation(UUID id) { return id.toString(); }
static UUID fromRepresentation (string id) { return parseUUID(id); }

But it is apparently not working. So, my question is - what should I do?

Thanks,
Martin

Re: Serialization of custom non-extensible structs (e.g. UUID)

On Wed, 07 Oct 2015 12:03:04 GMT, Martin Drasar wrote:

Hi,

I was wondering if it is possible to have vibe.d (de)serialize custom types that cannot be reasonable extended by providing toRepresentation/fromRepresentation, e.g. UUID struct from std.uuid.

After checking the isCustomSerializable trait, I tried to use this code:

string toRepresentation(UUID id) { return id.toString(); }
static UUID fromRepresentation (string id) { return parseUUID(id); }

But it is apparently not working. So, my question is - what should I do?

Thanks,
Martin

Two possibilities, either use a wrapper struct:

struct UUIDWrapper {
    UUID value;
    alias value this;
    string toString() const { return value.toString(); }
    static UUID fromString(string str) { return UUID(str); }
}

assert(uuid.serializeToJson() == Json(uuid.toString()));

or use the serialization policy feature:

template Policy(T) if (is(T == UUID)) {
    static string toRepresentation(UUID value) { return value.toString(); }
    static UUID fromRepresentation(string str) { return UUID(str); }
}

assert(uuid.serializeWithPolicy!(JsonSerializer, Policy) == Json(uuid.toString());

Re: Serialization of custom non-extensible structs (e.g. UUID)

On Fri, 09 Oct 2015 19:36:46 GMT, Sönke Ludwig wrote:

Two possibilities, either use a wrapper struct:

struct UUIDWrapper {
    UUID value;
    alias value this;
    string toString() const { return value.toString(); }
    static UUID fromString(string str) { return UUID(str); }
}

assert(uuid.serializeToJson() == Json(uuid.toString()));

or use the serialization policy feature:

template Policy(T) if (is(T == UUID)) {
    static string toRepresentation(UUID value) { return value.toString(); }
    static UUID fromRepresentation(string str) { return UUID(str); }
}

assert(uuid.serializeWithPolicy!(JsonSerializer, Policy) == Json(uuid.toString());

Hi,

the wrapper seems a bit clunky for my case, but I like the serialization policy. However, I am not sure, how to use the policy with the Rest interface generator.

Suppose I have this code:

struct SomeIDs
{
  UUID id1,
  UUID id2
}

interface API
{
  @property someIDs getIDs();
}

class RestServer : API
{
  private URLRouter _router;
  public:
    this() {
      _router = new URLRouter();
      _router.registerRestInterface(this, MethodStyle.camelCase);
    }
  ...
}

Where do I apply the policy?

Thanks,
Martin

Re: Serialization of custom non-extensible structs (e.g. UUID)

On Mon, 12 Oct 2015 20:46:35 GMT, Martin Drasar wrote:

Hi,

the wrapper seems a bit clunky for my case, but I like the serialization policy. However, I am not sure, how to use the policy with the Rest interface generator.

Suppose I have this code:

struct SomeIDs
{
  UUID id1,
  UUID id2
}

interface API
{
  @property someIDs getIDs();
}

class RestServer : API
{
  private URLRouter _router;
  public:
    this() {
      _router = new URLRouter();
      _router.registerRestInterface(this, MethodStyle.camelCase);
    }
  ...
}

Where do I apply the policy?

Thanks,
Martin

The REST interface indeed currently doesn't support policy customization. It's planned to enable general customization of the serialization in some form and at that point it would become possible. But until then, you'd either have to go with the wrapper, or add to/fromRepresentation to SomeIDs.

Adding a @serializationPolicy!Policy attribute to be recognized by the REST interface would also be relatively straight-forward, so that could also be an option. It would just have to be thought through completely to avoid conflicts with possible future extensions.