ctrlgen 0.3.2

Generate enums for message-passing services
Documentation
# ctrlgen-rs

A fork of [vi/trait-enumizer](https://github.com/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.

## Differences to trait-enumizer:
 - ctrlgen only supports inherent impls, it will not enumize traits.
 - ctrlgen prefers generating impls of traits over inherent functions, to
   make it more transparent to the user what is done. For example, the call function
   is implemented by implementing the `CallMut` trait on the enum.
 - ctrlgen tries to minimize and simplify the argument syntax, at the cost of some configurability.
   For example, the call trait will always be implemented.
 - ctrlgen requires the nightly rust channel for (amongst other things) GATs
 - ctrlgen supports generics in the struct definition (but not in the method signatures)
 - Proxies are implemented slightly differently, and are generally simpler. However, they currently
   don't support a lot of the options trait-enumizer has.
 - Proxies with async senders are currently not implemented
 - Async return value senders are currently not implemented.
 - no_std support is untested/unimplemented, but will be easy to do.

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.

## Example

```rust,ignore
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:

```rust,ignore
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 {}
```
## Returnval

By setting the `returnval = <Trait>` parameter, you configure the channel over which return values are sent.
`<Trait>` must implement `ctrlgen::Returnval`. 

Example Implementation:

```rust,ignore
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)
    }
}
```