use std::{
cell::RefCell,
fmt,
io::{self, ErrorKind, IoSlice, Write},
rc::Rc,
};
#[derive(Debug)]
pub struct RcOptionWriter<W> {
inner: Rc<RefCell<Option<W>>>,
}
#[inline]
fn writer_removed() -> io::Error {
io::Error::new(ErrorKind::BrokenPipe, "the writer has been removed out")
}
impl<W> Clone for RcOptionWriter<W> {
#[inline]
fn clone(&self) -> Self {
Self {
inner: self.inner.clone()
}
}
}
impl<W> From<Rc<RefCell<Option<W>>>> for RcOptionWriter<W> {
#[inline]
fn from(writer: Rc<RefCell<Option<W>>>) -> Self {
Self::new(writer)
}
}
impl<W> RcOptionWriter<W> {
#[inline]
pub const fn new(writer: Rc<RefCell<Option<W>>>) -> Self {
Self {
inner: writer
}
}
#[inline]
pub const fn get_ref(&self) -> &Rc<RefCell<Option<W>>> {
&self.inner
}
#[inline]
pub fn into_inner(self) -> Rc<RefCell<Option<W>>> {
self.inner
}
#[inline]
pub fn try_into_writer(self) -> Option<W> {
Rc::into_inner(self.inner).and_then(RefCell::into_inner)
}
}
impl<W: Write> Write for RcOptionWriter<W> {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match self.inner.borrow_mut().as_mut() {
Some(writer) => writer.write(buf),
None => Err(writer_removed()),
}
}
#[inline]
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
match self.inner.borrow_mut().as_mut() {
Some(writer) => writer.write_vectored(bufs),
None => Err(writer_removed()),
}
}
#[inline]
fn flush(&mut self) -> io::Result<()> {
match self.inner.borrow_mut().as_mut() {
Some(writer) => writer.flush(),
None => Err(writer_removed()),
}
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
match self.inner.borrow_mut().as_mut() {
Some(writer) => writer.write_all(buf),
None => Err(writer_removed()),
}
}
#[inline]
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
match self.inner.borrow_mut().as_mut() {
Some(writer) => writer.write_fmt(fmt),
None => Err(writer_removed()),
}
}
}