Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use dynamic dispatch to simplify reporters #10086

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

charliermarsh
Copy link
Member

@charliermarsh charliermarsh commented Dec 21, 2024

Summary

Sort of undecided on this. These are already stored as dyn Reporter in each struct, so we're already using dynamic dispatch in that sense. But all the methods take impl Reporter. This is sometimes nice (the callsites are simpler?), but it also means that in practice, you often can't pass None to these methods that accept Option<impl Reporter>, because Rust can't infer the generic type.

Anyway, this adds more consistency and simplifies the setup by using Arc<dyn Reporter> everywhere.

@charliermarsh charliermarsh enabled auto-merge (squash) December 21, 2024 23:45
@charliermarsh charliermarsh added the internal A refactor or improvement that is not user-facing label Dec 21, 2024
self.reporter.clone().map(Facade::from),
self.reporter
.clone()
.map(Facade::from)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really annoyed by this whole Facade setup... I want to be able to do something like:

impl <T: Reporter> uv_distribution::Reporter for Arc<dyn T> {
    fn on_build_start(&self, source: &BuildableSource) -> usize {
        self.on_build_start(source)
    }

    fn on_build_complete(&self, source: &BuildableSource, id: usize) {
        self.on_build_complete(source, id);
    }

    fn on_checkout_start(&self, url: &Url, rev: &str) -> usize {
        self.on_checkout_start(url, rev)
    }

    fn on_checkout_complete(&self, url: &Url, rev: &str, id: usize) {
        self.on_checkout_complete(url, rev, id);
    }
}

But I run into orphan trait problems.

The general problem here is that I have multiple Reporter traits. And if you implement one of them, then you should get some others "for free". But for now, I have to do this:

/// A facade for converting from [`Reporter`] to [`uv_git::Reporter`].
pub(crate) struct Facade {
    reporter: Arc<dyn Reporter>,
}

impl From<Arc<dyn Reporter>> for Facade {
    fn from(reporter: Arc<dyn Reporter>) -> Self {
        Self { reporter }
    }
}

impl uv_git::Reporter for Facade {
    fn on_checkout_start(&self, url: &Url, rev: &str) -> usize {
        self.reporter.on_checkout_start(url, rev)
    }

    fn on_checkout_complete(&self, url: &Url, rev: &str, id: usize) {
        self.reporter.on_checkout_complete(url, rev, id);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internal A refactor or improvement that is not user-facing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant