Hello,
I'm a newcomer to Rust after working quite a bit with dynamic languages such as Matlab, Python and Julia. I am currently in the process of translating a pet project of mine from Julia to Rust and would like to hear your opinions regarding the code structure.
The aforementioned pet project is a library for simulating electrical motors. The active part of an electrical motor consists of a rotor and a stator lamination. The stator has a winding, of which there are multiple types. The rotor may have magnets or a winding itself. There are also multiple types of laminations (e.g. slotted and non-slotted).
In the previous iteration of the library, I used the following architecture to represent a motor:
struct Motor{
Rotor: ActivePart,
Stator: ActivePart,
}
struct ActivePart{
Lamination: Lamination,
Winding: SomeWindingType,
}
struct WindingType1{
...
}
struct WindingType2{
...
}
The real code has of course quite a few more variants, but I hope I get the point across. Basically, a motor is a struct of structs of structs ... . In the Julia implementation, I used generics for SomeWindingType
to avoid loss of performance, which can be translated easily via generic traits to Rust. However, Rust also offers me the possibility to use an enum instead. And if I wouldn't mind the performance loss, a dynamic trait would also be an option, however I actually do mind, so this is out of the question
The problem with the generic approach from my perspective is: For structs high up in the hierarchy (e.g. ActivePart
), I would get quite a few <T,Q,R,S,...>
in the struct definition, due to the high variance of substructs. This leads to a LOT of specialized functions, which from my understanding would result in bloated binaries and high compilation times (which is actually a problem I encounter in Julia a lot due to my approach).
Using enums would solve this problem nicely. Also, the different variants can be expected to have roughly the same memory footprint, which also points me towards using enums. However, if I want to publish the library as a crate, other users wouldn't be able to define e.g. their own winding type (which is where traits would come in handily).
So I am very interested in your opinion. How would you structure this code? If you have a third option I didn't list, I am eager to hear it as well!