Recently, I’ve been having to write a lot of contract-driven code. I’ve been needing to use conditional compilation upon modules, ensuring that the modules provide the same external interface. Unfortunately, modules do not have traits, so I’ve had to reinterpret ‘modules’ as ‘static struct types’. For example:
trait MyTrait {
fn foo();
}
struct A {}
struct B {}
impl MyTrait for A {
fn foo() {
// Do something
}
}
impl MyTrait for B {
fn foo() {
// Do something else
}
}
#[cfg(config_variable = "A")] use A as MyFakeModule;
#[cfg(config_variable = "B")] use B as MyFakeModule;
fn do_something() {
MyFakeModule::foo();
}
Here, A and B are contractually obliged to implement the same ‘MyTrait’ interface. There are a few problems with this approach:
- There’s a useless empty struct declaration
- The syntax
use MyFakeModule::x::y::z;
doesn’t work, with complaints that MyFakeModule is not a module. - I run into this problem: https://github.com/rust-lang/rust/issues/38078
This would be 10 times easier to do if modules could implement traits, or if there way such a thing as ‘module traits’. Alternatively, is there another way to improve this?