jamesmunns / postcard-rpc

An RPC layer for postcard based protocols
Apache License 2.0
90 stars 21 forks source link

`endpoints!` and `topics!` macros don't accept generic type parameters #56

Open jamesmunns opened 2 weeks ago

jamesmunns commented 2 weeks ago

In v0.10, I made it so that endpoints and topics could accept types with lifetimes, e.g.:

topics! {
    list = TOPICS_IN_LIST;
    direction = postcard_rpc::TopicDirection::ToServer;
    | TopicTy       | MessageTy             | Path      | Cfg                           |
    | ----------    | ---------             | ----      | ---                           |
    | ZetaTopic1    | ZMsg                  | "zeta1"   |                               |
    | BorrowTopic   | Message<'a>           | "msg1"    | cfg(feature = "alpha")        |
    | BorrowTopic   | DoubleMessage<'a, 'b> | "msg1"    | cfg(not(feature = "alpha"))   |
}

However I wasn't able to figure out how to accept lifetimes AND/OR types, which means that generic types require an alias. This doesn't work (because we try and interpret the stuff between <> as lifetimes):

topics! {
    list = TOPICS_IN_LIST;
    direction = postcard_rpc::TopicDirection::ToServer;
    | TopicTy       | MessageTy             | Path      |
    | ----------    | ---------             | ----      |
    | ZetaTopic1    | Result<u16, u32>      | "zeta1"   |
}

But this does:

pub type ZetaAlias = Result<u16, u32>;
topics! {
    list = TOPICS_IN_LIST;
    direction = postcard_rpc::TopicDirection::ToServer;
    | TopicTy       | MessageTy             | Path      |
    | ----------    | ---------             | ----      |
    | ZetaTopic1    | ZetaAlias             | "zeta1"   |
}

This is not good UX, and should be fixed. I am open to improvements of the macro syntax to re-allow this, it will likely require some kind of fancier tt-muncher or something to separately collect the types and generics.

jamesmunns commented 2 weeks ago

Note that this also applies to some other types, like arrays ([u8; 16]) or tuples ((u32, u8, i32)), which will also require an alias.