Skip to content

#[cglue_trait] macro panicking when trait has multiple types #26

Description

@ppom0

Hi! I'm trying to define a plugin API that permits to define multiple implementations of the same trait. (Actually multiple implementations of 2 different traits, be let's keep it simple)

So here's the business logic trait:

#[cglue_trait]
#[cglue_forward]
pub trait StreamImpl {
    fn start(&mut self) -> RResult<(), RString>;
    fn next(&mut self) -> RResult<ROption<RString>, RString>;
    fn close(&mut self) -> RResult<(), RString>;
}

I'm writing a PluginRoot trait, which compiles:

#[cglue_trait]
pub trait PluginRoot {
    type StreamImpl0: StreamImpl + 'static;

    /// Return all stream types that should be made available to reaction users
    fn stream_impls(&self) -> RVec<RString>;

    /// Return one instance of the first type
    fn stream_impl0(
        &mut self,
        config: RValue,
    ) -> ROption<Self::StreamImpl0>;
}

Ideally I'd just have one stream_impl function that returns a Box<dyn StreamImpl>, but I understand I can't do this, so I try to explicitly write that multiple implementations of my trait can be provided.

But if I want to add a second implementation of this trait, the macro panics:

#[cglue_trait]
pub trait PluginRoot {
    type StreamImpl0: StreamImpl + 'static;
    type StreamImpl1: StreamImpl + 'static;

    /// Return all stream types that should be made available to reaction users
    fn stream_impls(&self) -> RVec<RString>;

    /// Return one instance of a given type.
    fn stream_impl0(
        &mut self,
        config: RValue,
    ) -> ROption<Self::StreamImpl0>;

    /// Return one instance of a given type.
    fn stream_impl1(
        &mut self,
        config: RValue,
    ) -> ROption<Self::StreamImpl1>;

I also tried writing 2 traits:

#[cglue_trait]
pub trait PluginRootStream0 {
    type StreamImpl0: StreamImpl + 'static;
    fn stream_impl0_name(&self) -> ROption<RString>;
    fn stream_impl0(
        &mut self,
        config: RValue,
    ) -> ROption<Self::StreamImpl0>;
}

#[cglue_trait]
pub trait PluginRootStream1 {
    type StreamImpl1: StreamImpl + 'static;
    fn stream_impl1_name(&self) -> ROption<RString>;
    fn stream_impl1(
        &mut self,
        config: RValue,
    ) -> ROption<Self::StreamImpl1>;
}

But then I can't group them, both of those macro invocations fail:

// error: struct takes 2 generic arguments but 1 generic argument was supplied
cglue_trait_group!(PluginRoot, {}, { PluginRootStream0, PluginRootStream1 });

// error: trait takes 0 generic arguments but 1 generic argument was supplied
cglue_trait_group!(
    PluginRoot<S0: StreamImpl + 'static, S1: StreamImpl + 'static>,
    {},
    { PluginRootStream0<S0>, PluginRootStream1<S1> }
);

I wonder if my case is supported at all, or if I'm just misinterpreting the doc and going in a wrong direction.

Thank you for this library, can't wait to unlock its potential :)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions