Is there a better alternative to Rc>>>?
⚓ Rust 📅 2026-01-05 👤 surdeus 👁️ 5My requirement is to make a wrapper over an inner AsyncWrite (lets call it MyWriter) which would provide the following features:
- Have cheap cloning (reusing underlying AsyncWrite to push new bytes anytime by any of the multiple owners of the reference)
- Have interior mutability (because I loop over the owners which are basically independent futures that eventually resolve and write bytes into their copy of
MyWriter)
This is the naive version of putting the Pin needed by AsyncWrite, and Box needed to Deref inside the classic Rc<RefCell<..>>> combo
pub struct MyWriter<W> {
inner_writer: Rc<RefCell<Pin<Box<W>>>>
}
impl<W> MyWriter<W> where W: AsyncWrite {
fn poll_write(
self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &[u8],
) -> std::task::Poll<std::io::Result<usize>> {
let mut writer_b: std::cell::RefMut<'_, Pin<Box<W>>> = self.inner_writer.borrow_mut();
let writer_pinned: Pin<&mut W> = writer_b.deref_mut().as_mut();
writer_pinned.poll_write(cx, buf)
}
// And similar impl of poll_flush & poll_close
}
It seems to work, but my main concern is the interaction with Pin because I'm not sure whether I'm doing something wrong by having it stored inside a RefCell. Also the impl of AsyncWrite methods feels like bruteforcing a Pin<&mut W> out of this structure just to be able to use its own AsyncWrite methods. So, is there a better alternative?
I found PinCell crate which allows pin-safe version of interior mutability, to be able to use projections on a Pin<PinCell<W>>, but I couldn't figure out the cloning part, because cloning the above leads to a deep copy of W, and putting an Rc on top (like Rc<Pin<PinCell<W>>>) doesn't allow to obtain the owned Pin<&mut W> needed to call the inner W's AsyncWrite methods
Edit: It's a single-threaded (Sync + !Send) environment, hence no Arc or Mutex
2 posts - 2 participants
🏷️ Rust_feed