From 8db4c8c41482de5eeaa0b12a90d0280704956b81 Mon Sep 17 00:00:00 2001 From: Ivan Kalinin Date: Mon, 30 Sep 2024 16:58:48 +0200 Subject: [PATCH] Add `IoWriter` --- Cargo.toml | 2 +- src/traits.rs | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c570f4a..8000cae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "tl-proto" description = "A collection of traits for working with TL serialization/deserialization" authors = ["Ivan Kalinin "] repository = "https://github.com/broxus/tl-proto" -version = "0.4.8" +version = "0.4.9" edition = "2021" include = ["src/**/*.rs", "README.md"] license = "MIT" diff --git a/src/traits.rs b/src/traits.rs index f0863d7..9f42741 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -206,6 +206,75 @@ impl TlPacket for bytes::BytesMut { } } +/// A wrapper type for writing to [`std::io::Write`] types. +/// +/// Ignores all errors afther the first one. +/// The status can be retrieved using [`Writer::into_parts`]. +pub struct IoWriter { + writer: W, + status: std::io::Result<()>, +} + +impl IoWriter { + /// Creates a new writer. + pub const fn new(writer: W) -> Self { + Self { + writer, + status: Ok(()), + } + } + + /// Gets a mutable reference to the underlying writer. + pub fn get_mut(&mut self) -> &mut W { + &mut self.writer + } + + /// Gets a reference to the underlying writer. + pub fn get_ref(&self) -> &W { + &self.writer + } + + /// Disassembles the [`Writer`], returning the underlying writer, and the status. + pub fn into_parts(self) -> (W, std::io::Result<()>) { + (self.writer, self.status) + } +} + +impl TlPacket for IoWriter { + const TARGET: TlTarget = TlTarget::Packet; + + #[inline(always)] + fn write_u32(&mut self, data: u32) { + if self.status.is_ok() { + self.status = self.writer.write_all(&data.to_le_bytes()); + } + } + + fn write_i32(&mut self, data: i32) { + if self.status.is_ok() { + self.status = self.writer.write_all(&data.to_le_bytes()); + } + } + + fn write_u64(&mut self, data: u64) { + if self.status.is_ok() { + self.status = self.writer.write_all(&data.to_le_bytes()); + } + } + + fn write_i64(&mut self, data: i64) { + if self.status.is_ok() { + self.status = self.writer.write_all(&data.to_le_bytes()); + } + } + + fn write_raw_slice(&mut self, data: &[u8]) { + if self.status.is_ok() { + self.status = self.writer.write_all(data); + } + } +} + /// TL packet type. #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum TlTarget {