I’ve been playing around with rewriting some java libraries in rust, but I keep hitting a wall, probably because of my background. I’ve experience in C++ where I can do a lot of black magic using template metaprogramming + operator overloading and java where the magic comes from runtime reflection, and I’m having trouble avoiding the “shut up compiler, I know what I’m doing” way of thinking.
Here is the deal:
This particular java library defines a interface that allows client code to define managers for different kinds of objects. Say, if a object needs to be shared of the network then I can declare a Shared interface and implement a ManageShared class that extends from the Manager interface. Similarly, if a object is a signal from a hardware I can declare a Signal interface and implement a ManageSignal class. An object may be managed by more then one manager (i.e., it may implement Shared and Signal). The common hierarchy of managers allows us to create a dispatcher that sends the objects to their correct managers at run time (a ManagersManager, if you will (Java, am I right?)).
One of the biggest problems with the current state of this library is the insane amount of cyclical dependencies, singletons and race conditions caused by objects being initialized out of order in some circumstances. So as an exercise I’ve being slowly rewriting it in rust, mostly as an exercise. In general it’s been easy enough removing the cyclical dependencies and singletons, and the way rust language rules work forces me to rethink the way different parts of the system interact with each other. At the same time I’m trying to keep the concepts as close as possible to the original library as not to alienate possible users.
Story time over, here are my pain points:
Objects that are shared over the network are serialized to json (serde_json) and sent over the wire. Now, on the other side how can I call the correct deserializer? The lack of runtime reflection in rust makes it so I can’t save the type of the object as a field during the serialization and call Its constructor through reflection on the other end. I’ve tried mapping the type identifier to a deserializer function but I can never get it quite to work…
Like I said, the same object might be managed by many managers through different interfaces. I’ve been using trait objects to emulate that, but I can’t get everything to work together. Right now I’m mostly using Rc for simplicity sake (so I don’t have to deal with lifetimes), but I can’t get a object to be a Rc of trait object A on ManagerA and Rc of trait object B on ManagerB.
I’m having trouble dealing with dynamically sending objects to the correct managers. Because I can’t check instanceof the type at runtime I don’t really know what to do…
Sorry about the wall of text. Hope someone can help me.
Just an observation: Rust has been incredible when writing something from scratch, but rewriting something from a managed languages might be the closest I’ve been to have a programming task make me cry.