httplz_ext/
lib.rs

1use std::io::{Read, Result as IOResult};
2
3pub struct NotEnoughSpace;
4pub struct Buf<T, U> {
5	written_len: usize,
6	data: T,
7	_dt: core::marker::PhantomData<U>,
8}
9impl<T, U> Buf<T, U> {
10	pub fn new(data: T) -> Self {
11		Self {
12			data,
13			written_len: 0,
14			_dt: Default::default(),
15		}
16	}
17}
18
19impl<T, U> Buf<T, U>
20where
21	T: AsRef<[U]>,
22{
23	pub fn remaining(&self) -> &[U] {
24		&self.data.as_ref()[self.written_len..]
25	}
26
27	pub fn filled(&self) -> &[U] {
28		&self.data.as_ref()[..self.written_len]
29	}
30}
31
32impl<T, U> Buf<T, U>
33where
34	T: AsRef<[U]>,
35	T: AsMut<[U]>,
36{
37	pub fn remaining_mut(&mut self) -> &mut [U] {
38		&mut self.data.as_mut()[self.written_len..]
39	}
40
41	pub fn extend_from_slice(&mut self, s: &[U]) -> Result<(), NotEnoughSpace>
42	where
43		U: Copy,
44	{
45		if self.remaining().len() < s.len() {
46			return Err(NotEnoughSpace);
47		}
48
49		self.remaining_mut()[..s.len()].copy_from_slice(s);
50		self.written_len += s.len();
51
52		Ok(())
53	}
54
55	pub fn clear(&mut self) {
56		self.written_len = 0;
57	}
58
59	pub fn pop_front_alloc(&mut self, amt: usize)
60	where
61		U: Copy + Default,
62	{
63		let to_copy = &self.filled()[amt..];
64		let buf_sz = to_copy.len();
65		let mut buf = vec![Default::default(); buf_sz].into_boxed_slice();
66		buf.copy_from_slice(to_copy);
67		self.clear();
68		let _ = self.extend_from_slice(&buf);
69	}
70
71	pub fn pop_front(&mut self, amt: usize)
72	where
73		U: Copy,
74	{
75		if amt > self.filled().len() {
76			panic!("Filled not big enough");
77		}
78
79		let data = self.data.as_mut();
80
81		let src = &data[amt..];
82		let count = data.len() - amt;
83
84		// SAFETY:
85		// - src comes from data
86		// - U is copy
87		// - count is within bounds of data
88		unsafe { core::ptr::copy(src.as_ptr(), data.as_mut_ptr(), count) }
89
90		self.written_len -= amt;
91	}
92}
93
94impl<T> Buf<T, u8>
95where
96	T: AsRef<[u8]> + AsMut<[u8]>,
97{
98	pub fn read_from(&mut self, mut r: impl Read) -> IOResult<usize> {
99		let remaining = self.remaining_mut();
100		let amt = r.read(remaining)?;
101
102		self.written_len += amt;
103
104		Ok(amt)
105	}
106}
107
108impl<T> httplz::Write for Buf<T, u8>
109where
110	T: AsRef<[u8]> + AsMut<[u8]>,
111{
112	fn write(&mut self, buf: &[u8]) -> httplz::Written {
113		self.extend_from_slice(buf)
114			.map_err(|_| httplz::ErrorKind::BufNotBigEnough.into())
115	}
116}