Hi everyone!
I am writing a library for an embedded device that
- communicates over the serial port
(I am creating 2 threads for it 1 for listening, 1 for writing), - receives protobuf data,
- parses it into struct,
- runs user-defined callback depending on the struct received,
- writes back the response.
This is how the generated protobuf structs approx looks like so you have an idea:
pub mod message {
#[derive(Clone, PartialEq, ::prost::Oneof)]
pub enum Payload {
#[prost(message, tag="1")]
EnableCommand(super::EnableCommand),
#[prost(message, tag="2")]
DisableCommand(super::DisableCommand),
}
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct EnableCommand {
#[prost(string, tag="1")]
pub user_id: ::prost::alloc::string::String,
#[prost(string, tag="2")]
pub transaction_id: ::prost::alloc::string::String,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct DisableCommand {
}
I have problem with implementation how to let user define the callback that will be called once the message(struct) is received.
In C I would just use weak functions so the user is able to overwrite the behaviour for each struct.
I don't know if there is something similar in Rust.
What I've tried so far:
- I've tried to use the traits with empty default implementation. This look perfect at first glance, but in order for user to overwrite the default trait implementation either trait or struct must be declared on the user side, not library side.
The trait is, however, defined in the library, and the struct the trait should be implemented for is generated by prost (protobuf serialization lib) also in the library. - I've tried to create a struct with callbacks
pub struct Callbacks {
pub enable_command: Box<dyn Fn(&EnableCommand) -> ()>,
pub disable_command: Box<dyn Fn(&DisableCommand) -> ()>,
}
and let user provide this struct on the initialization of the library. This is also not working, because the Box<dyn Fn()> is not Send, and I can't use it in the thread.
What am I missing here, or are there more elegant approaches to it?
I appreciate your help, I am quite new to Rust and may be not aware of common approaches for library development.