Using default impl of trait wihout adding blanket implementation

Hi,

In a project I'm working on, I have a trait A that defines an interface. Furthermore, I have a trait, let's call it ExportA, that relies on A, which is used to export object implementing A to a certain format. ExportA contains a default implementation, which can be overridden by the user:

trait A { /* ... */ }

trait ExportA: A
{
   fn export(&self) -> MyResult<String>
   {
       /* ... */
   }
}

This works fine, and I can use the default functionality of ExportA if I add an empty implementation of the trait:

struct  MyA
{
    /* ... */
}

impl A for MyA
{
   /* ... */
}

impl ExportA for MyA {}

Now, what I would like, is that users of my crate don't have to add this empty implementation. In some cases the export functionality is not used, sometimes the default implementation just suffices, and having to add implementations for traits that aren't used just leads to a lot of unnecessary boiler plating. I can't add a default implementation for all objects implementing A, like

impl<T: A> ExportA for T {}

because then the default implementation is always used (what /is/ the status of specialization BTW?). Another solution would be to move the functionality of ExportA into A proper, but I'd prefer not to that either, since the export really is orthogonal to what A provides.

So, how would I go about it then? Any help would be greatly appreciated!

The easiest way seems to export a macros which, given the list of idents, creates these empty impls. Something like this (playground):

macro_rules! derive_export {
    ($($name:ident),+) => {
        $(
            impl ExportA for $name {}
        )+
    }
}

struct A;
struct B;
struct C;

derive_export!(A, B);

The idiomatic way perhaps would be to make a custom derive, but this is something I can't give any advise with.

I think the idiomatic way is to write a custom derive macro. Then when your user wants the default implementation, they can [#derive(ExportA)].

https://doc.rust-lang.org/beta/book/ch19-06-macros.html#how-to-write-a-custom-derive-macro

2 Likes

Thanks. The thought of using a macro had occurred to me, but I was hoping to avoid yet another one :slight_smile:

This looks very promising, I didnt know it was possible to write derive macros. Thanks for pointing me in this direction!

And thank you both for taking the time to read this and help me out. It is very much appreciated!

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.