either icon indicating copy to clipboard operation
either copied to clipboard

FEATURE REQUEST: some (attribute?) macro to implement our trait for Either easily

Open anatawa12 opened this issue 2 years ago • 6 comments

I think it might be useful to implement our (object-safe) trait for either easily with some attribute macro

anatawa12 avatar Dec 22 '23 08:12 anatawa12

Do you have an example of what you're looking for?

Generally, I would expect this to be generically implemented in your own crate, like:

impl<L: YourTrait, R: YourTrait> YourTrait for Either<L, R> { ... }

Or you could write your own proc-macro #[derive] for types that contain Either, or maybe a macro_rules! implementation, but I think it's not something we can do from the either crate itself.

cuviper avatar Dec 29 '23 21:12 cuviper

I want some macro to generate like this

impl<L: RepoSource, R: RepoSource> RepoSource for Either<L, R> {
    fn cache_path(&self) -> &Path {
        for_both!(self, src => src.cache_path())
    }

    fn headers(&self) -> &IndexMap<String, String> {
        for_both!(self, src => src.headers())
    }

    fn url(&self) -> Option<&Url> {
        for_both!(self, src => src.url())
    }
}

from code like this

#[either::implement_for_either]
pub(crate) trait RepoSource {
    fn cache_path(&self) -> &Path;
    fn headers(&self) -> &IndexMap<String, String>;
    fn url(&self) -> Option<&Url>;
}

anatawa12 avatar Jan 04 '24 05:01 anatawa12

I see. Generating a blanket impl doesn't seem too bad when the arguments and return types are independent of Self or associated types, similar to trait object safety. But consider a trait like this:

trait GetParent {
    fn get_parent(&self) -> Option<&Self>;
}

A blanket impl on Either<L, R> could pass that call to the inner types, but there's no way to wrap their Option<&L> or Option<&R> to an Option<&Either<L, R>>.

That said, I did find an existing macro crate: https://crates.io/crates/either_trait_macro

cuviper avatar Jan 04 '24 18:01 cuviper