1 // SPDX-License-Identifier: Apache-2.0 2 3 //! Simple, Low-level I/O traits 4 //! 5 //! This crate provides two simple traits: `Read` and `Write`. These traits 6 //! mimic their counterparts in `std::io`, but are trimmed for simplicity 7 //! and can be used in `no_std` and `no_alloc` environments. Since this 8 //! crate contains only traits, inline functions and unit structs, it should 9 //! be a zero-cost abstraction. 10 //! 11 //! If the `std` feature is enabled, we provide blanket implementations for 12 //! all `std::io` types. If the `alloc` feature is enabled, we provide 13 //! implementations for `Vec<u8>`. In all cases, you get implementations 14 //! for byte slices. You can, of course, implement the traits for your own 15 //! types. 16 17 #![cfg_attr(not(feature = "std"), no_std)] 18 #![deny(missing_docs)] 19 #![deny(clippy::all)] 20 #![deny(clippy::cargo)] 21 #[cfg(android_dylib)] 22 extern crate std; 23 24 #[cfg(feature = "alloc")] 25 extern crate alloc; 26 27 /// A trait indicating a type that can read bytes 28 /// 29 /// Note that this is similar to `std::io::Read`, but simplified for use in a 30 /// `no_std` context. 31 pub trait Read { 32 /// The error type 33 type Error; 34 35 /// Reads exactly `data.len()` bytes or fails read_exact(&mut self, data: &mut [u8]) -> Result<(), Self::Error>36 fn read_exact(&mut self, data: &mut [u8]) -> Result<(), Self::Error>; 37 } 38 39 /// A trait indicating a type that can write bytes 40 /// 41 /// Note that this is similar to `std::io::Write`, but simplified for use in a 42 /// `no_std` context. 43 pub trait Write { 44 /// The error type 45 type Error; 46 47 /// Writes all bytes from `data` or fails write_all(&mut self, data: &[u8]) -> Result<(), Self::Error>48 fn write_all(&mut self, data: &[u8]) -> Result<(), Self::Error>; 49 50 /// Flushes all output flush(&mut self) -> Result<(), Self::Error>51 fn flush(&mut self) -> Result<(), Self::Error>; 52 } 53 54 #[cfg(feature = "std")] 55 impl<T: std::io::Read> Read for T { 56 type Error = std::io::Error; 57 58 #[inline] read_exact(&mut self, data: &mut [u8]) -> Result<(), Self::Error>59 fn read_exact(&mut self, data: &mut [u8]) -> Result<(), Self::Error> { 60 self.read_exact(data) 61 } 62 } 63 64 #[cfg(feature = "std")] 65 impl<T: std::io::Write> Write for T { 66 type Error = std::io::Error; 67 68 #[inline] write_all(&mut self, data: &[u8]) -> Result<(), Self::Error>69 fn write_all(&mut self, data: &[u8]) -> Result<(), Self::Error> { 70 self.write_all(data) 71 } 72 73 #[inline] flush(&mut self) -> Result<(), Self::Error>74 fn flush(&mut self) -> Result<(), Self::Error> { 75 self.flush() 76 } 77 } 78 79 #[cfg(not(feature = "std"))] 80 impl<R: Read + ?Sized> Read for &mut R { 81 type Error = R::Error; 82 83 #[inline] read_exact(&mut self, data: &mut [u8]) -> Result<(), Self::Error>84 fn read_exact(&mut self, data: &mut [u8]) -> Result<(), Self::Error> { 85 (**self).read_exact(data) 86 } 87 } 88 89 #[cfg(not(feature = "std"))] 90 impl<W: Write + ?Sized> Write for &mut W { 91 type Error = W::Error; 92 93 #[inline] write_all(&mut self, data: &[u8]) -> Result<(), Self::Error>94 fn write_all(&mut self, data: &[u8]) -> Result<(), Self::Error> { 95 (**self).write_all(data) 96 } 97 98 #[inline] flush(&mut self) -> Result<(), Self::Error>99 fn flush(&mut self) -> Result<(), Self::Error> { 100 (**self).flush() 101 } 102 } 103 104 /// An error indicating there are no more bytes to read 105 #[cfg(not(feature = "std"))] 106 #[derive(Debug)] 107 pub struct EndOfFile(()); 108 109 #[cfg(not(feature = "std"))] 110 impl Read for &[u8] { 111 type Error = EndOfFile; 112 113 #[inline] read_exact(&mut self, data: &mut [u8]) -> Result<(), Self::Error>114 fn read_exact(&mut self, data: &mut [u8]) -> Result<(), Self::Error> { 115 if data.len() > self.len() { 116 return Err(EndOfFile(())); 117 } 118 119 let (prefix, suffix) = self.split_at(data.len()); 120 data.copy_from_slice(prefix); 121 *self = suffix; 122 Ok(()) 123 } 124 } 125 126 /// An error indicating that the output cannot accept more bytes 127 #[cfg(not(feature = "std"))] 128 #[derive(Debug)] 129 pub struct OutOfSpace(()); 130 131 #[cfg(not(feature = "std"))] 132 impl Write for &mut [u8] { 133 type Error = OutOfSpace; 134 135 #[inline] write_all(&mut self, data: &[u8]) -> Result<(), Self::Error>136 fn write_all(&mut self, data: &[u8]) -> Result<(), Self::Error> { 137 if data.len() > self.len() { 138 return Err(OutOfSpace(())); 139 } 140 141 let (prefix, suffix) = core::mem::take(self).split_at_mut(data.len()); 142 prefix.copy_from_slice(data); 143 *self = suffix; 144 Ok(()) 145 } 146 147 #[inline] flush(&mut self) -> Result<(), Self::Error>148 fn flush(&mut self) -> Result<(), Self::Error> { 149 Ok(()) 150 } 151 } 152 153 #[cfg(all(not(feature = "std"), feature = "alloc"))] 154 impl Write for alloc::vec::Vec<u8> { 155 type Error = core::convert::Infallible; 156 157 #[inline] write_all(&mut self, data: &[u8]) -> Result<(), Self::Error>158 fn write_all(&mut self, data: &[u8]) -> Result<(), Self::Error> { 159 self.extend_from_slice(data); 160 Ok(()) 161 } 162 163 #[inline] flush(&mut self) -> Result<(), Self::Error>164 fn flush(&mut self) -> Result<(), Self::Error> { 165 Ok(()) 166 } 167 } 168 169 #[cfg(test)] 170 mod test { 171 use super::*; 172 173 #[test] read_eof()174 fn read_eof() { 175 let mut reader = &[1u8; 0][..]; 176 let mut buffer = [0u8; 1]; 177 178 reader.read_exact(&mut buffer[..]).unwrap_err(); 179 } 180 181 #[test] read_one()182 fn read_one() { 183 let mut reader = &[1u8; 1][..]; 184 let mut buffer = [0u8; 1]; 185 186 reader.read_exact(&mut buffer[..]).unwrap(); 187 assert_eq!(buffer[0], 1); 188 189 reader.read_exact(&mut buffer[..]).unwrap_err(); 190 } 191 192 #[test] read_two()193 fn read_two() { 194 let mut reader = &[1u8; 2][..]; 195 let mut buffer = [0u8; 1]; 196 197 reader.read_exact(&mut buffer[..]).unwrap(); 198 assert_eq!(buffer[0], 1); 199 200 reader.read_exact(&mut buffer[..]).unwrap(); 201 assert_eq!(buffer[0], 1); 202 203 reader.read_exact(&mut buffer[..]).unwrap_err(); 204 } 205 206 #[test] 207 #[cfg(feature = "std")] read_std()208 fn read_std() { 209 let mut reader = std::io::repeat(1); 210 let mut buffer = [0u8; 2]; 211 212 reader.read_exact(&mut buffer[..]).unwrap(); 213 assert_eq!(buffer[0], 1); 214 assert_eq!(buffer[1], 1); 215 } 216 217 #[test] write_oos()218 fn write_oos() { 219 let mut writer = &mut [0u8; 0][..]; 220 221 writer.write_all(&[1u8; 1][..]).unwrap_err(); 222 } 223 224 #[test] write_one()225 fn write_one() { 226 let mut buffer = [0u8; 1]; 227 let mut writer = &mut buffer[..]; 228 229 writer.write_all(&[1u8; 1][..]).unwrap(); 230 writer.write_all(&[1u8; 1][..]).unwrap_err(); 231 assert_eq!(buffer[0], 1); 232 } 233 234 #[test] write_two()235 fn write_two() { 236 let mut buffer = [0u8; 2]; 237 let mut writer = &mut buffer[..]; 238 239 writer.write_all(&[1u8; 1][..]).unwrap(); 240 writer.write_all(&[1u8; 1][..]).unwrap(); 241 writer.write_all(&[1u8; 1][..]).unwrap_err(); 242 assert_eq!(buffer[0], 1); 243 assert_eq!(buffer[1], 1); 244 } 245 246 #[test] 247 #[cfg(feature = "alloc")] write_vec()248 fn write_vec() { 249 let mut buffer = alloc::vec::Vec::new(); 250 251 buffer.write_all(&[1u8; 1][..]).unwrap(); 252 buffer.write_all(&[1u8; 1][..]).unwrap(); 253 254 assert_eq!(buffer.len(), 2); 255 assert_eq!(buffer[0], 1); 256 assert_eq!(buffer[1], 1); 257 } 258 259 #[test] 260 #[cfg(feature = "std")] write_std()261 fn write_std() { 262 let mut writer = std::io::sink(); 263 264 writer.write_all(&[1u8; 1][..]).unwrap(); 265 writer.write_all(&[1u8; 1][..]).unwrap(); 266 } 267 } 268