Channel for sending types that implement a non-dyn compatible trait

I am currently implementing the actor pattern for a Zigbee library. I want to use a tokio::sync::mpsc::channel to send command frames to the actor. However the commands are distinct types, but which implement a common trait Command. Alas, Command is not dyn compatible because it has associated constants, such as the command ID and direction.

use crate::cluster::Cluster;
use crate::direction::Direction;

/// Trait to identify a Zigbee command.
pub trait Command: Cluster {
    /// The command identifier.
    const ID: u8;

    /// The command direction.
    const DIRECTION: Direction;
}

Is there another way of sending the different types through a channel short of using a humongous enum to account for all possible types?

If Cluster is dyn-compatible, you could consider

pub trait DynCommand: Cluster {
    fn id(&self) -> u8;
    fn direction(&self) -> Direction;
}

impl<T: Command> DynCommand for T {
    fn id(&self) -> u8 {
        <Self as Command>::ID
    }
    fn direction(&self) -> Direction {
        <Self as Command>::DIRECTION
    }
}

Thanks, that sounds promising. Alas, it is not:

/// Trait to identify Zigbee clusters.
pub trait Cluster {
    /// The cluster identifier.
    const ID: u16;
}

But I guess I could also introduce a DynCluster in the same way?

Or just remove the : Cluster bound on DynCommand and add a fn cluster_id(&self) -> u16 if you need it.

Thanks for you help. I, however, went a different way and abstracted the generics away from the communication channel. I.e. The proxy trait, used for communicating with the actor now has all the generics in its public API and serializes those accordingly, sending just more or less raw bytes via the channel to the actor. This made some things on the actor side a bit more tricky, but simplified the channel API a lot.