Dependency inversion and the orphan rule

⚓ Rust    📅 2026-04-14    👤 surdeus    👁️ 3      

surdeus

I 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

Read full topic

🏷️ Rust_feed