Add an upcast_arc function to NetDirProvider.

This uses some apparently-standard trickery to implement a function
that lets us upcast from Arc<dyn Subtrait> to Arc<dyn Supertrait>.

I considered as alternatives `as_dyn_trait` and `cast_dyn_object`.
Both were nice, but generated a far larger interface than this.
This commit is contained in:
Nick Mathewson 2022-06-02 16:53:21 -04:00
parent 6f96736278
commit 0e6a54351d
1 changed files with 27 additions and 1 deletions

View File

@ -279,7 +279,7 @@ pub enum DirEvent {
/// An object that can provide [`NetDir`]s, as well as inform consumers when
/// they might have changed.
pub trait NetDirProvider {
pub trait NetDirProvider: UpcastArcNetDirProvider {
/// Return a handle to our latest directory, if we have one.
fn latest_netdir(&self) -> Option<Arc<NetDir>>;
@ -305,6 +305,32 @@ where
}
}
/// Helper trait: allows any `Arc<X>` to be upcast to a `Arc<dyn
/// NetDirProvider>` if X is an implementation or supertrait of NetDirProvider.
///
/// This trait exists to work around a limitation in rust: when trait upcasting
/// coercion is stable, this will be unnecessary.
///
/// The Rust tracking issue is <https://github.com/rust-lang/rust/issues/65991>.
pub trait UpcastArcNetDirProvider {
/// Return a view of this object as an `Arc<dyn NetDirProvider>`
fn upcast_arc<'a>(self: Arc<Self>) -> Arc<dyn NetDirProvider + 'a>
where
Self: 'a;
}
impl<T> UpcastArcNetDirProvider for T
where
T: NetDirProvider + Sized,
{
fn upcast_arc<'a>(self: Arc<Self>) -> Arc<dyn NetDirProvider + 'a>
where
Self: 'a,
{
self
}
}
/// A partially build NetDir -- it can't be unwrapped until it has
/// enough information to build safe paths.
#[derive(Debug, Clone)]