From 6d1f28eb79c6c70b058fcbae5047dbd744764149 Mon Sep 17 00:00:00 2001 From: cel 🌸 Date: Fri, 30 May 2025 13:29:02 +0100 Subject: doc: everything --- src/writer/endable.rs | 37 ++++++++++++++++++++++++++++ src/writer/loggable.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 src/writer/endable.rs create mode 100644 src/writer/loggable.rs (limited to 'src/writer') diff --git a/src/writer/endable.rs b/src/writer/endable.rs new file mode 100644 index 0000000..6d842f3 --- /dev/null +++ b/src/writer/endable.rs @@ -0,0 +1,37 @@ +use crate::Error; + +#[derive(Debug)] +pub struct Endable { + inner: T, + ended: bool, +} + +impl Endable { + pub fn new(inner: T) -> Self { + Self { + inner, + ended: false, + } + } + + pub fn end(&mut self) { + self.ended = true; + } + + pub fn into_inner(self) -> T { + self.inner + } + + #[inline(always)] + pub fn try_as_mut(&mut self) -> Result<&mut T, Error> { + if self.ended { + Err(Error::RootElementEnded) + } else { + Ok(&mut self.inner) + } + } + + pub fn ignore_end(&mut self) -> &mut T { + &mut self.inner + } +} diff --git a/src/writer/loggable.rs b/src/writer/loggable.rs new file mode 100644 index 0000000..dd69668 --- /dev/null +++ b/src/writer/loggable.rs @@ -0,0 +1,67 @@ +use std::{fmt::Display, mem, pin::pin, task::Poll}; + +use futures::ready; +use pin_project::pin_project; +pub use tokio::io::AsyncWrite; + +#[pin_project] +#[derive(Debug)] +pub struct Loggable { + log_buffer: Vec, + #[pin] + writer: W, +} + +impl Loggable { + pub fn new(writer: W) -> Self { + Self { + log_buffer: Vec::new(), + writer, + } + } + + pub fn into_inner(self) -> W { + self.writer + } + + pub fn take_log(&mut self) -> Vec { + let log: Vec = mem::replace(&mut self.log_buffer, Vec::new()); + log + } +} + +impl Display for Loggable { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let str = str::from_utf8(&self.log_buffer).unwrap_or("buffer to string conversion failed"); + f.write_str(str) + } +} + +impl AsyncWrite for Loggable { + fn poll_write( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &[u8], + ) -> std::task::Poll> { + let this = self.as_mut().project(); + let ready = ready!(this.writer.poll_write(cx, buf)); + self.log_buffer.extend_from_slice(buf); + Poll::Ready(ready) + } + + fn poll_flush( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + let this = self.project(); + Poll::Ready(ready!(this.writer.poll_flush(cx))) + } + + fn poll_shutdown( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + let this = self.project(); + Poll::Ready(ready!(this.writer.poll_shutdown(cx))) + } +} -- cgit