Dependency inversion and the orphan rule
⚓ Rust 📅 2026-04-14 👤 surdeus 👁️ 3I am facing a Rust-specific implementation / design issue.
I have a crate, let's call it zigbee, which implements a Zigbee-specific smart home API.
I have another crate, let's call itsmarthomelib, which abstracts across different smart home protocols.
I want the latter crate smarthomelib to expose a generic interface for smart home protocols, such as Zigbee, but also other protocols, such as Matter/Thread.
Now I don't want smarthomelib to know anything about possible smart home protocols or their libraries. It shall expose only a common API, which the other crates implement (-> dependency inversion).
In the zigbee crate, I now have something like
impl<T> crate::ColorControlZigbee for T {} which implements color control functionality on the Zigbee level. For any such implementation I could implement
impl<T> smarthomelib::GenericColorControl for T
where
T: crate::ColorControlZigbee
{
}
in terms of business logic, but of course I'm struck now by the orphan rule.
My current "workaround" is to just implement smarthomelib::GenericColorControl for a concrete type as exposed by the zigbee crate, but I find this unsatisfactory.
Do you have any suggestions on how I can have my cake and eat it?
I don't want to couple smarthomelib back to zigbee and I want anything that implements zigbee::ColorControlZigbee to also implement smarthomelib::GenericColorControl.
Is there a trick or something, which I can apply?
How do you approach issues like this?
2 posts - 2 participants
🏷️ Rust_feed