1use core::fmt;
2use core::mem::take;
3
4use musli::{Buf, Context};
5
6#[cfg(feature = "alloc")]
7use alloc::vec::Vec;
8
9pub const MAX_FIXED_BYTES_LEN: usize = 128;
11
12#[derive(Debug)]
14pub(crate) struct SliceOverflow {
15 n: usize,
16 capacity: usize,
17}
18
19impl fmt::Display for SliceOverflow {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 let SliceOverflow { n, capacity } = self;
22
23 write!(
24 f,
25 "Tried to write {n} bytes to slice, with a remaining capacity of {capacity}"
26 )
27 }
28}
29
30pub trait Writer {
32 type Mut<'this>: Writer
43 where
44 Self: 'this;
45
46 fn borrow_mut(&mut self) -> Self::Mut<'_>;
48
49 fn write_buffer<C, B>(&mut self, cx: &C, buffer: B) -> Result<(), C::Error>
51 where
52 C: ?Sized + Context,
53 B: Buf;
54
55 fn write_bytes<C>(&mut self, cx: &C, bytes: &[u8]) -> Result<(), C::Error>
57 where
58 C: ?Sized + Context;
59
60 #[inline]
62 fn write_byte<C>(&mut self, cx: &C, b: u8) -> Result<(), C::Error>
63 where
64 C: ?Sized + Context,
65 {
66 self.write_bytes(cx, &[b])
67 }
68}
69
70impl<W> Writer for &mut W
71where
72 W: ?Sized + Writer,
73{
74 type Mut<'this> = &'this mut W where Self: 'this;
75
76 #[inline]
77 fn borrow_mut(&mut self) -> Self::Mut<'_> {
78 self
79 }
80
81 #[inline]
82 fn write_buffer<C, B>(&mut self, cx: &C, buffer: B) -> Result<(), C::Error>
83 where
84 C: ?Sized + Context,
85 B: Buf,
86 {
87 (*self).write_buffer(cx, buffer)
88 }
89
90 #[inline]
91 fn write_bytes<C>(&mut self, cx: &C, bytes: &[u8]) -> Result<(), C::Error>
92 where
93 C: ?Sized + Context,
94 {
95 (*self).write_bytes(cx, bytes)
96 }
97
98 #[inline]
99 fn write_byte<C>(&mut self, cx: &C, b: u8) -> Result<(), C::Error>
100 where
101 C: ?Sized + Context,
102 {
103 (*self).write_byte(cx, b)
104 }
105}
106
107#[cfg(feature = "alloc")]
108impl Writer for Vec<u8> {
109 type Mut<'this> = &'this mut Self where Self: 'this;
110
111 #[inline]
112 fn borrow_mut(&mut self) -> Self::Mut<'_> {
113 self
114 }
115
116 #[inline]
117 fn write_buffer<C, B>(&mut self, cx: &C, buffer: B) -> Result<(), C::Error>
118 where
119 C: ?Sized + Context,
120 B: Buf,
121 {
122 self.write_bytes(cx, buffer.as_slice())
124 }
125
126 #[inline]
127 fn write_bytes<C>(&mut self, cx: &C, bytes: &[u8]) -> Result<(), C::Error>
128 where
129 C: ?Sized + Context,
130 {
131 self.extend_from_slice(bytes);
132 cx.advance(bytes.len());
133 Ok(())
134 }
135
136 #[inline]
137 fn write_byte<C>(&mut self, cx: &C, b: u8) -> Result<(), C::Error>
138 where
139 C: ?Sized + Context,
140 {
141 self.push(b);
142 cx.advance(1);
143 Ok(())
144 }
145}
146
147impl Writer for &mut [u8] {
148 type Mut<'this> = &'this mut Self where Self: 'this;
149
150 #[inline]
151 fn borrow_mut(&mut self) -> Self::Mut<'_> {
152 self
153 }
154
155 #[inline]
156 fn write_buffer<C, B>(&mut self, cx: &C, buffer: B) -> Result<(), C::Error>
157 where
158 C: ?Sized + Context,
159 B: Buf,
160 {
161 self.write_bytes(cx, buffer.as_slice())
163 }
164
165 #[inline]
166 fn write_bytes<C>(&mut self, cx: &C, bytes: &[u8]) -> Result<(), C::Error>
167 where
168 C: ?Sized + Context,
169 {
170 if self.len() < bytes.len() {
171 return Err(cx.message(SliceOverflow {
172 n: bytes.len(),
173 capacity: self.len(),
174 }));
175 }
176
177 let next = take(self);
178 let (this, next) = next.split_at_mut(bytes.len());
179 this.copy_from_slice(bytes);
180 *self = next;
181 Ok(())
182 }
183
184 #[inline]
185 fn write_byte<C>(&mut self, cx: &C, b: u8) -> Result<(), C::Error>
186 where
187 C: ?Sized + Context,
188 {
189 if self.is_empty() {
190 return Err(cx.message(format_args!(
191 "Buffer overflow, remaining is {} while tried to write 1",
192 self.len()
193 )));
194 }
195
196 self[0] = b;
197 *self = &mut take(self)[1..];
198 Ok(())
199 }
200}
201
202pub struct BufWriter<T> {
204 buf: T,
205}
206
207impl<T> BufWriter<T> {
208 pub fn new(buf: T) -> Self {
210 Self { buf }
211 }
212
213 pub fn into_inner(self) -> T {
215 self.buf
216 }
217}
218
219impl<T> Writer for BufWriter<T>
220where
221 T: Buf,
222{
223 type Mut<'this> = &'this mut Self
224 where
225 Self: 'this;
226
227 #[inline(always)]
228 fn borrow_mut(&mut self) -> Self::Mut<'_> {
229 self
230 }
231
232 #[inline(always)]
233 fn write_buffer<C, B>(&mut self, cx: &C, buffer: B) -> Result<(), C::Error>
234 where
235 C: ?Sized + Context,
236 B: Buf,
237 {
238 if !self.buf.write(buffer.as_slice()) {
239 return Err(cx.message("Buffer overflow"));
240 }
241
242 Ok(())
243 }
244
245 #[inline(always)]
246 fn write_bytes<C>(&mut self, cx: &C, bytes: &[u8]) -> Result<(), C::Error>
247 where
248 C: ?Sized + Context,
249 {
250 if !self.buf.write(bytes) {
251 return Err(cx.message("Buffer overflow"));
252 }
253
254 Ok(())
255 }
256}