Current state
I’m working on the IC WebSocket Rust CDK. Like in a traditional WebSocket server, the developer can pass to the IC WebSocket CDK the events’ function callbacks (on_open
, on_message
, on_close
). These functions are stored in the WsHandlers.
At the current state, when a message is received by the canister, it is passed to the OnMessageCallback as raw encoded Candid bytes and the developer needs to decode it manually as done in the example:
Goal
We want to make it possible for developers to receive the message already decoded based on a type that they provide. For this reason, the OnMessageCallback arguments should have a dynamic message
field type like:
/// Arguments passed to the `on_message` handler.
pub struct OnMessageCallbackArgs {
pub client_principal: ClientPrincipal,
pub message: Box<dyn CandidType>,
}
This way, when a new message is received by the canister in the ws_message function, the message can be decoded from Candid and the callback called with the correct type (how it’s done now: https://github.com/omnia-network/ic-websocket-cdk-rs/blob/ec6d2fcb1bfdf3fc887007d14350e282bdbc9abb/src/ic-websocket-cdk/src/lib.rs#L988-L991).
Question
However, the compiler is giving this error:
error[E0038]: the trait `CandidType` cannot be made into an object
--> src/ic-websocket-cdk/src/lib.rs:794:22
|
794 | pub message: Box<dyn CandidType>,
| ^^^^^^^^^^^^^^ `CandidType` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
Does anyone has any suggestions on how to make it work? Should we change the way the developer provides the events callbacks to the CDK?