How can I cast Bson (vibe.d) to various struct types? The best would be to get rid of the switch statement as well.

It works fine deserializing when casting directly collection.findOne!UserCreate(), but when I try from a Bson object I get below error directly.

What to do?

The error I get when using event.get!UserCreate() is the following:

    store ~master: building configuration "application"...
/home/tirithen/.dub/packages/vibe-d-0.8.6/vibe-d/data/vibe/data/bson.d(603,4): Error: static assert: "Cannot cast const(Bson) to 'UserCreate'." source/app.d(100,23): instantiated from here: get!(UserCreate)
    /usr/bin/dmd failed with exit code 1.

The relevant part of the code looks like this:

    module store.app;

    import std.stdio : writeln;
    import std.uuid : UUID, randomUUID;
    import std.datetime.systime : SysTime;
    import std.datetime.timezone : UTC;
    import std.typecons : Nullable;
    import std.exception : enforce;
    import vibe.d : runApplication;
    import vibe.db.mongo.mongo : MongoCollection, connectMongoDB;
    import vibe.data.bson : Bson, fromBsonData;

    import store.hash : hashString;
    import store.events;
    import store.mongo.mongo;
    import store.mongo.lock;

    struct UserCreate
    {
        EventMeta meta;
        string username;
        string email;

        void applyTo(ref User user)
        {
                user.username = this.username;
                user.email = this.email;
        }
    }

    struct UserChangePassword
    {
        EventMeta meta;
        string password;

        void applyTo(ref User user)
        {
                user.password = this.password;
        }
    }

    struct UserChangeUsername
    {
        EventMeta meta;
        string username;

        void applyTo(ref User user)
        {
                user.username = this.username;
        }
    }

    struct UserChangeEmail
    {
        EventMeta meta;
        string email;

        void applyTo(ref User user)
        {
                user.unverifiedEmail = this.email;
        }
    }

    struct UserVerifiedEmail
    {
        EventMeta meta;
        string email;

        void applyTo(ref User user)
        {
                user.email = this.email;
                user.unverifiedEmail = "";
        }
    }

    struct User
    {
        Meta meta;
        string username;
        string email;
        string unverifiedEmail;
        string password;
    }

    User loadUser(MongoCollection collection, UUID streamId)
    {
        auto user = User();
auto userEvents = collection.find(Bson(["meta.streamId": Bson(streamId)]));

        foreach (Bson event; userEvents)
        {
                string type = event["meta"]["type"].get!string;
                writeln("type: ", type);
                switch (type)
                {
                default:
writeln("No handler found for type " ~ type ~ ", skipping event.");
                        break;
                case "UserCreate":
                        applyTo(user, event.get!UserCreate());
                        break;
                case "UserChangePassword":
                        applyTo(user, event.get!UserChangePassword());
                        break;
                case "UserChangeUsername":
                        applyTo(user, event.get!UserChangeUsername());
                        break;
                case "UserChangeEmail":
                        applyTo(user, event.get!UserChangeEmail());
                        break;
                case "UserVerifiedEmail":
                        applyTo(user, event.get!UserVerifiedEmail());
                        break;
                }
        }

        return user;
    }

    void main()
    {
        auto connection = Mongo("127.0.0.1", "testing");

MongoCollection userEvents = connection.getCollection("userEvents");
        createEventIndexes(userEvents);

auto user = loadUser(userEvents, UUID("95395448-e1b5-458c-a309-6e6842d06505"));
        writeln(user);

        runApplication();
    }

Reply via email to