www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Can't read mongo result back to structs with vibe.d Bson serializer

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();
     }
Dec 10 2019