Crates.io | ctrlgen |
lib.rs | ctrlgen |
version | 0.3.2 |
source | src |
created_at | 2022-09-29 14:52:09.405651 |
updated_at | 2023-09-06 09:51:02.711052 |
description | Generate enums for message-passing services |
homepage | |
repository | |
max_upload_size | |
id | 676718 |
size | 28,803 |
A fork of vi/trait-enumizer that attempts to be easier to use, while sacrificing a bit of flexibility.
Documentation to come. See docs of trait-enumizer, and examples here for now.
CallMut
trait on the enum.Most of the efforts here could probably be merged into trait-enumizer, but i was in a hurry, so i implemented the features i needed instead.
struct Service<T: From<i32>> {
counter: T,
}
#[ctrlgen::ctrlgen(
pub enum ServiceMsg,
trait ServiceProxy,
returnval = TokioRetval,
)]
impl Service {
pub fn increment_by(&mut self, arg: i32) -> i32 {
self.counter = arg;
self.counter
}
}
This will generate something similar to the following code:
pub enum ServiceMsg
where TokioRetval: ::ctrlgen::Returnval,
{
IncrementBy {
arg: i32,
ret: <TokioRetval as ::ctrlgen::Returnval>::Sender<i32>,
},
}
impl ::ctrlgen::CallMut<Service> for ServiceMsg
where TokioRetval: ::ctrlgen::Returnval,
{
type Output = core::result::Result<(), <TokioRetval as ::ctrlgen::Returnval>::SendError>;
fn call_mut(self, this: &mut Service) -> Self::Output {
match self {
Self::IncrementBy { arg, ret } => {
<TokioRetval as ::ctrlgen::Returnval>::send(ret, this.increment_by(arg))
}
}
}
}
pub trait ServiceProxy: ::ctrlgen::Proxy<ServiceMsg>
{
fn increment_by(&self, arg: i32) -> <TokioRetval as ::ctrlgen::Returnval>::RecvResult<i32> {
let ret = <TokioRetval as ::ctrlgen::Returnval>::create();
let msg = ServiceMsg::IncrementBy { arg, ret: ret.0 };
::ctrlgen::Proxy::send(self, msg);
<TokioRetval as ::ctrlgen::Returnval>::recv(ret.1)
}
}
impl<T: ::ctrlgen::Proxy<ServiceMsg>> ServiceProxy for T {}
By setting the returnval = <Trait>
parameter, you configure the channel over which return values are sent.
<Trait>
must implement ctrlgen::Returnval
.
Example Implementation:
pub struct FailedToSendRetVal;
pub struct TokioRetval;
impl Returnval for TokioRetval {
type Sender<T> = promise::Sender<T>;
type Receiver<T> = promise::Promise<T>;
type SendError = FailedToSendRetVal;
type RecvResult<T> = promise::Promise<T>;
fn create<T>() -> (Self::Sender<T>, Self::Receiver<T>) {
promise::Promise::channel()
}
fn recv<T>(rx: Self::Receiver<T>) -> Self::RecvResult<T> {
rx
}
fn send<T>(tx: Self::Sender<T>, msg: T) -> core::result::Result<(), Self::SendError> {
tx.send(msg).map_err(|_| FailedToSendRetVal)
}
}