1use core::mem::take;
5use crate::{DataSink, Error, Result};
6
7impl DataSink for &mut [u8] {
8 fn write_bytes(&mut self, buf: &[u8]) -> Result {
9 mut_slice_write_bytes(self, buf, <[u8]>::copy_from_slice)
10 }
11
12 fn write_utf8_codepoint(&mut self, value: char) -> Result {
13 if let Some((buf, remaining)) = take(self).split_at_mut_checked(value.len_utf8()) {
14 value.encode_utf8(buf);
16 *self = remaining;
17 Ok(())
18 } else {
19 let mut buf = [0; 4];
21 self.write_utf8(value.encode_utf8(&mut buf))
22 }
23 }
24
25 fn write_u8(&mut self, value: u8) -> Result {
26 use core::convert::identity;
27 mut_slice_push_u8(self, value, identity)
28 }
29
30 fn write_i8(&mut self, value: i8) -> Result {
31 self.write_u8(value as u8)
32 }
33}
34
35#[cfg(feature = "unstable_uninit_slice")]
36use core::mem::MaybeUninit;
37
38#[cfg(feature = "unstable_uninit_slice")]
39impl DataSink for &mut [MaybeUninit<u8>] {
40 fn write_bytes(&mut self, buf: &[u8]) -> Result {
41 mut_slice_write_bytes(self, buf, |t, s| { t.write_copy_of_slice(s); })
42 }
43
44 fn write_u8(&mut self, value: u8) -> Result {
45 mut_slice_push_u8(self, value, MaybeUninit::new)
46 }
47
48 fn write_i8(&mut self, value: i8) -> Result {
49 self.write_u8(value as u8)
50 }
51}
52
53#[allow(clippy::mut_mut)]
54fn mut_slice_write_bytes<T>(
55 sink: &mut &mut [T],
56 buf: &[u8],
57 copy_from_slice: impl FnOnce(&mut [T], &[u8])
58) -> Result {
59 let len = buf.len().min(sink.len());
60 let (target, empty) = take(sink).split_at_mut(len);
62 *sink = empty;
63 copy_from_slice(target, &buf[..len]);
64 let remaining = buf.len() - len;
65 if remaining > 0 {
66 Err(Error::overflow(remaining))
67 } else {
68 Ok(())
69 }
70}
71
72#[allow(clippy::mut_mut)]
73fn mut_slice_push_u8<T>(
74 sink: &mut &mut [T],
75 value: u8,
76 map: impl FnOnce(u8) -> T
77) -> Result {
78 if sink.is_empty() {
79 Err(Error::overflow(1))
80 } else {
81 sink[0] = map(value);
82 *sink = &mut take(sink)[1..];
83 Ok(())
84 }
85}