1#[cfg(feature = "alloc")]
2use alloc::vec::Vec;
3#[cfg(not(feature = "std"))]
4use core::fmt;
5#[cfg(feature = "std")]
6use std::io;
7
8use crate::error;
9
10#[cfg(not(feature = "unsealed_read_write"))]
11pub trait Write: private::Sealed {
20 #[doc(hidden)]
22 type Error: Into<error::Error>;
23
24 #[doc(hidden)]
26 fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
27}
28
29#[cfg(feature = "unsealed_read_write")]
30pub trait Write {
42 type Error: Into<error::Error>;
44
45 fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
47}
48
49#[cfg(not(feature = "unsealed_read_write"))]
50mod private {
51 pub trait Sealed {}
52}
53
54impl<W> Write for &mut W
55where
56 W: Write,
57{
58 type Error = W::Error;
59
60 fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
61 (*self).write_all(buf)
62 }
63}
64
65#[cfg(not(feature = "unsealed_read_write"))]
66impl<W> private::Sealed for &mut W where W: Write {}
67
68#[cfg(feature = "std")]
69#[derive(Debug)]
73pub struct IoWrite<W>(W);
74
75#[cfg(feature = "std")]
76impl<W: io::Write> IoWrite<W> {
77 pub const fn new(w: W) -> Self {
79 Self(w)
80 }
81}
82
83#[cfg(feature = "std")]
84impl<W: io::Write> Write for IoWrite<W> {
85 type Error = io::Error;
86
87 fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
88 self.0.write_all(buf)
89 }
90}
91
92#[cfg(all(feature = "std", not(feature = "unsealed_read_write")))]
93impl<W> private::Sealed for IoWrite<W> where W: io::Write {}
94
95#[cfg(any(feature = "std", feature = "alloc"))]
96impl Write for Vec<u8> {
97 type Error = error::Error;
98
99 fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
100 self.extend_from_slice(buf);
101 Ok(())
102 }
103}
104
105#[cfg(all(
106 any(feature = "std", feature = "alloc"),
107 not(feature = "unsealed_read_write")
108))]
109impl private::Sealed for Vec<u8> {}
110
111#[cfg(not(feature = "std"))]
112#[derive(Debug)]
113pub struct FmtWrite<'a, W: Write>(&'a mut W);
114
115#[cfg(not(feature = "std"))]
116impl<'a, W: Write> FmtWrite<'a, W> {
117 pub const fn new(w: &'a mut W) -> Self {
119 FmtWrite(w)
120 }
121}
122
123#[cfg(not(feature = "std"))]
124impl<W: Write> fmt::Write for FmtWrite<'_, W> {
125 fn write_str(&mut self, s: &str) -> fmt::Result {
126 self.0.write_all(s.as_bytes()).map_err(|_| fmt::Error)
127 }
128}
129
130#[cfg(all(not(feature = "std"), not(feature = "unsealed_read_write")))]
131impl<W> private::Sealed for FmtWrite<'_, W> where W: Write {}
132
133#[derive(Debug)]
137pub struct SliceWrite<'a> {
138 slice: &'a mut [u8],
139 index: usize,
140}
141
142impl<'a> SliceWrite<'a> {
143 pub const fn new(slice: &'a mut [u8]) -> Self {
145 SliceWrite { slice, index: 0 }
146 }
147
148 #[must_use]
150 pub const fn bytes_written(&self) -> usize {
151 self.index
152 }
153
154 #[must_use]
156 pub const fn into_inner(self) -> &'a mut [u8] {
157 self.slice
158 }
159}
160
161impl Write for SliceWrite<'_> {
162 type Error = error::Error;
163
164 fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
165 if self.slice.len() - self.index < buf.len() {
166 return Err(error::Error::scratch_too_small(self.index as u64));
168 }
169 let end = self.index + buf.len();
170 self.slice[self.index..end].copy_from_slice(buf);
171 self.index = end;
172 Ok(())
173 }
174}
175
176#[cfg(not(feature = "unsealed_read_write"))]
177impl private::Sealed for SliceWrite<'_> {}