data_streams/
wrappers.rs

1// Copyright 2024 - Strixpyrr
2// SPDX-License-Identifier: Apache-2.0
3
4#[cfg(feature = "alloc")]
5use alloc::boxed::Box;
6use crate::{BufferAccess, DataSink, Result};
7#[cfg(not(feature = "unstable_specialization"))]
8use crate::{DataSource, source::default_read_array};
9
10// Todo: DataSource couldn't be implemented for &mut <source> when specialization
11//  is enabled.
12
13// This was a PITA to get working. Did this save much time? No idea
14macro_rules! delegate_impl {
15    (with $reduced:expr;
16	$(
17	fn $name:ident($($params:tt)+)$( -> $ret:ty)?;
18	)+) => {
19		$(fn $name($($params)+)$( -> $ret)? {
20			delegate_impl!(@$reduced;$name($($params)+))
21		})+
22	};
23	(@$reduced:expr;$name:ident(&$(mut)? self$(, $param:ident: $param_ty:ty)*)) => {
24		$reduced.$name($($param),*)
25	};
26}
27
28macro_rules! impl_buf_access {
29    ($($(#[$attr:meta])? impl<$gen:ident> for $ty:ty;)+) => {
30		$(
31		$(#[$attr])?
32		impl<$gen: BufferAccess + ?Sized> BufferAccess for $ty {
33			delegate_impl! {
34				with **self;
35				fn buffer_capacity(&self) -> usize;
36				fn buffer(&self) -> &[u8];
37				fn fill_buffer(&mut self) -> Result<&[u8]>;
38				fn clear_buffer(&mut self);
39				fn drain_buffer(&mut self, count: usize);
40			}
41		})+
42	};
43}
44
45impl_buf_access! {
46	impl<S> for &mut S;
47	#[cfg(feature = "alloc")]
48	impl<S> for Box<S>;
49}
50
51macro_rules! impl_source {
52    ($($(#[$attr:meta])? impl<$gen:ident> for $ty:ty;)+) => {
53		$(
54		$(#[$attr])?
55		impl<$gen: DataSource + ?Sized> DataSource for $ty {
56			delegate_impl! {
57				with **self;
58				fn available(&self) -> usize;
59				fn request(&mut self, count: usize) -> Result<bool>;
60				fn skip(&mut self, count: usize) -> Result<usize>;
61				fn require(&mut self, count: usize) -> Result;
62				fn read_u8(&mut self) -> Result<u8>;
63				fn read_i8(&mut self) -> Result<i8>;
64				fn read_u16(&mut self) -> Result<u16>;
65				fn read_i16(&mut self) -> Result<i16>;
66				fn read_u16_le(&mut self) -> Result<u16>;
67				fn read_i16_le(&mut self) -> Result<i16>;
68				fn read_u32(&mut self) -> Result<u32>;
69				fn read_i32(&mut self) -> Result<i32>;
70				fn read_u32_le(&mut self) -> Result<u32>;
71				fn read_i32_le(&mut self) -> Result<i32>;
72				fn read_u64(&mut self) -> Result<u64>;
73				fn read_i64(&mut self) -> Result<i64>;
74				fn read_u64_le(&mut self) -> Result<u64>;
75				fn read_i64_le(&mut self) -> Result<i64>;
76				fn read_u128(&mut self) -> Result<u128>;
77				fn read_i128(&mut self) -> Result<i128>;
78				fn read_u128_le(&mut self) -> Result<u128>;
79				fn read_i128_le(&mut self) -> Result<i128>;
80				fn read_usize(&mut self) -> Result<usize>;
81				fn read_isize(&mut self) -> Result<isize>;
82				fn read_usize_le(&mut self) -> Result<usize>;
83				fn read_isize_le(&mut self) -> Result<isize>;
84			}
85
86			fn read_bytes<'a>(&mut self, buf: &'a mut [u8]) -> Result<&'a [u8]> {
87				(**self).read_bytes(buf)
88			}
89
90			fn read_exact_bytes<'a>(&mut self, buf: &'a mut [u8]) -> Result<&'a [u8]> {
91				(**self).read_exact_bytes(buf)
92			}
93
94			fn read_array<const N: usize>(&mut self) -> Result<[u8; N]> {
95				default_read_array(&mut **self)
96			}
97
98			#[cfg(feature = "utf8")]
99			fn read_utf8<'a>(&mut self, buf: &'a mut [u8]) -> Result<&'a str> {
100				(**self).read_utf8(buf)
101			}
102		})+
103	};
104}
105
106impl_source! {
107	// Conflicts with specialized impl, because outside crates are allowed to implement
108	// this trait for mutable references of their type; &mut S is a "foreign type" in
109	// compiler terms. I don't know a way around this issue, so we'll disable it when
110	// specialization is enabled. Fixing this down the line shouldn't be a breaking change.
111	#[cfg(not(feature = "unstable_specialization"))]
112	impl<S> for &mut S;
113	#[cfg(all(feature = "alloc", not(feature = "unstable_specialization")))]
114	impl<S> for Box<S>;
115}
116
117macro_rules! impl_sink {
118    ($($(#[$attr:meta])? impl<$gen:ident> for $ty:ty;)+) => {
119		$(
120		$(#[$attr])?
121		impl<$gen: DataSink + ?Sized> DataSink for $ty {
122			delegate_impl! {
123				with **self;
124				fn write_bytes(&mut self, buf: &[u8]) -> Result;
125				fn write_utf8(&mut self, value: &str) -> Result;
126				fn write_u8(&mut self, value: u8) -> Result;
127				fn write_i8(&mut self, value: i8) -> Result;
128				fn write_u16(&mut self, value: u16) -> Result;
129				fn write_i16(&mut self, value: i16) -> Result;
130				fn write_u16_le(&mut self, value: u16) -> Result;
131				fn write_i16_le(&mut self, value: i16) -> Result;
132				fn write_u32(&mut self, value: u32) -> Result;
133				fn write_i32(&mut self, value: i32) -> Result;
134				fn write_u32_le(&mut self, value: u32) -> Result;
135				fn write_i32_le(&mut self, value: i32) -> Result;
136				fn write_u64(&mut self, value: u64) -> Result;
137				fn write_i64(&mut self, value: i64) -> Result;
138				fn write_u64_le(&mut self, value: u64) -> Result;
139				fn write_i64_le(&mut self, value: i64) -> Result;
140				fn write_u128(&mut self, value: u128) -> Result;
141				fn write_i128(&mut self, value: i128) -> Result;
142				fn write_u128_le(&mut self, value: u128) -> Result;
143				fn write_i128_le(&mut self, value: i128) -> Result;
144				fn write_usize(&mut self, value: usize) -> Result;
145				fn write_isize(&mut self, value: isize) -> Result;
146				fn write_usize_le(&mut self, value: usize) -> Result;
147				fn write_isize_le(&mut self, value: isize) -> Result;
148			}
149		}
150		)+
151	};
152}
153
154impl_sink! {
155	impl<S> for &mut S;
156	#[cfg(feature = "alloc")]
157	impl<S> for Box<S>;
158}