RejectedSoftware Forums

Sign up

Serialize with std.typecons.Typedef

Hi,

I'm trying out Vibe.D and really liking it so far. Thanks Sönke for the amazing work you have put into this.

I had one question for which I am unable to solve. I often use Typedef to make my code more typesafe. How can I use Typedef with Vibe.D's serialization framework?

For example, say I have:

alias QuestionId = Typedef!(int, -1, "QuestionId");
alias StudentId = Typedef!(int, -1, "StudentId");
enum Actions : int { skip, correct, incorrect }

struct QuestionAttempts
{
    StudentId studentId;
    QuestionId questionId;
    @byName Actions action;
}

Here, QuestionId and StudentId are wrappers on integers such that I don't allow them to mix. I do conversions to and from ints at the boundary (where I interact with the outside world via APIs, etc). That way I reduce the possibility of errors in my D code while communicating in the same manner with the outside world as if they were ints.

unittest
{
    auto str1 = "{\"studentId\":3,\"questionId\":42,\"action\":\"skip\"";
    auto qa1 = deserializeJson!QuestionAttempts(str1);
}

How can I get the above code to work? Any pointers would be greatly appreciated.

Thanks,
Saurabh

Re: Serialize with std.typecons.Typedef

PS: I got this to work:

template TypedefPolicy(T) if (!is(TypedefType!T == T))
{
    TypedefType!T toRepresentation(T t)
    {
        return cast(TypedefType!T)(t);
    }
    
    T fromRepresentation(TypedefType!T v)
    {
        return T(v);
    }
}
unittest
{
    import vibe.data.json;

    static assert(isPolicySerializable!(TypedefPolicy, QuestionId));
    Json serial2 = 42;
    QuestionId qi2 = deserializeWithPolicy!(JsonSerializer, TypedefPolicy, QuestionId)(serial2);
}

However I still cannot figure out how to serialize to QuestionAttempts as in the original post.

Re: Serialize with std.typecons.Typedef

Okay, sorry for posting so frequently. I've got it to work in 2 steps: by first converting it to a Json and then to the required struct:

    auto serialStr1 = "{\"studentId\":300453,\"questionId\":65708,\"questionRevision\":1,\"action\":\"correct\",\"timeTakenSeconds\":10,\"eventTimestamp\":\"2016-01-01T00:00:03\",\"metadata\":\"\",\"frontend\":\"\"}";
    auto j4 = parseJsonString(serialStr1);
    writeln(j4);
    auto ss4 = deserializeWithPolicy!(JsonSerializer, TypedefPolicy, QuestionAttempts)(j4);
    writeln(ss4);

Is this the idiomatic way to accomplish this task?

Also, if I'm making a REST interface using registerRestInterface, how can I pass tell registerRestInterface to use my custom policy?

Thanks,
Sorry again for making you read all the above posts uselessly.

Re: Serialize with std.typecons.Typedef

On Fri, 04 Nov 2016 11:51:39 GMT, Saurabh Das wrote:

Okay, sorry for posting so frequently. I've got it to work in 2 steps: by first converting it to a Json and then to the required struct:

    auto serialStr1 = "{\"studentId\":300453,\"questionId\":65708,\"questionRevision\":1,\"action\":\"correct\",\"timeTakenSeconds\":10,\"eventTimestamp\":\"2016-01-01T00:00:03\",\"metadata\":\"\",\"frontend\":\"\"}";
    auto j4 = parseJsonString(serialStr1);
    writeln(j4);
    auto ss4 = deserializeWithPolicy!(JsonSerializer, TypedefPolicy, QuestionAttempts)(j4);
    writeln(ss4);

Is this the idiomatic way to accomplish this task?

Did you try with deserializeWithPolicy!(JsonStringSeriailzer, TypedefPolicy, QuestionAttempts)(serialStr1)? That would avoid the dynamic memory allocations that are required for first converting to Json. Policy based serialization is still missing some convenience overloads, but I think there should be a version of deserializeJson that directly accepts a policy.

Also, if I'm making a REST interface using registerRestInterface, how can I pass tell registerRestInterface to use my custom policy?

Unfortunately this is not yet possible. It's planned to be added in conjunction with general support for custom serialization. Related issues: #1569, #1040, #1467

Thanks,
Sorry again for making you read all the above posts uselessly.

No problem at all! I know that all this serialization policy topic is not really well documented, yet.

Re: Serialize with std.typecons.Typedef

BTW, I'll add direct support for Typedef in the serialization
framework, so that defining a policy won't be necessary for this case.

Re: Serialize with std.typecons.Typedef

Am 10.11.2016 um 10:31 schrieb Sönke Ludwig:

BTW, I'll add direct support for Typedef in the serialization
framework, so that defining a policy won't be necessary for this case.

PR: #1617