+ fn block_disconnected(&mut self, header: &BlockHeader, height: u32);
+}
+
+pub(crate) mod sealed {
+ use super::*;
+ /// Rustc currently isn't smart enough to figure out that two impls are not conflicting when they
+ /// both impl for `Deref` but with a different `Target`
+ /// (https://github.com/rust-lang/rust/issues/20400). Instead, we use the workaround suggested at
+ /// https://stackoverflow.com/questions/40392524/conflicting-trait-implementations-even-though-associated-types-differ/40408431#40408431
+ pub trait DerefListen {
+ fn block_connected(&self, block: &Block, height: u32);
+ fn block_disconnected(&self, header: &BlockHeader, height: u32);
+ }
+ impl<T: Deref, U: Deref> DerefListen for (T, U) where T::Target: DerefListen, U::Target: DerefListen {
+ fn block_connected(&self, block: &Block, height: u32) {
+ Deref::deref(&self.0).block_connected(block, height);
+ Deref::deref(&self.1).block_connected(block, height);
+ }
+
+ fn block_disconnected(&self, header: &BlockHeader, height: u32) {
+ Deref::deref(&self.0).block_disconnected(header, height);
+ Deref::deref(&self.1).block_disconnected(header, height);
+ }
+ }
+}
+impl<T: Deref> Listen for T where T::Target: sealed::DerefListen {
+ fn block_connected(&mut self, block: &Block, height: u32) {
+ sealed::DerefListen::block_connected(Deref::deref(self), block, height);
+ }
+ fn block_disconnected(&mut self, header: &BlockHeader, height: u32) {
+ sealed::DerefListen::block_disconnected(Deref::deref(self), header, height);
+ }