binrw/binread/mod.rs
1mod impls;
2
3use crate::{
4 __private::Required,
5 io::{Read, Seek},
6 meta::ReadEndian,
7 BinResult, Endian,
8};
9pub use impls::VecArgs;
10
11/// The `BinRead` trait reads data from streams and converts it into objects.
12///
13/// This trait is usually derived, but can also be manually implemented by
14/// writing an appropriate [`Args`] type and [`read_options()`] function.
15///
16/// [`Args`]: Self::Args
17/// [`read_options()`]: Self::read_options
18///
19/// # Derivable
20///
21/// This trait can be used with `#[derive]` or `#[binread]`. Each field of a
22/// derived type must either implement `BinRead` or be annotated with an
23/// attribute containing a [`map`], [`try_map`], or [`parse_with`] directive.
24///
25/// [`map`]: crate::docs::attribute#map
26/// [`parse_with`]: crate::docs::attribute#custom-parserswriters
27/// [`try_map`]: crate::docs::attribute#map
28///
29/// Using `#[binread]` instead of `#[derive]` is required when using
30/// [temporary fields].
31///
32/// [temporary fields]: crate::docs::attribute#temp
33pub trait BinRead: Sized {
34 /// The type used for the `args` parameter of [`read_args()`] and
35 /// [`read_options()`].
36 ///
37 /// When the given type implements [`Default`], convenience functions like
38 /// [`read()`] are enabled. `BinRead` implementations that don’t receive any
39 /// arguments should use the `()` type.
40 ///
41 /// When `BinRead` is derived, the [`import`] and [`import_tuple`]
42 /// directives define this type.
43 ///
44 /// [`import`]: crate::docs::attribute#arguments
45 /// [`import_tuple`]: crate::docs::attribute#arguments
46 /// [`read()`]: Self::read
47 /// [`read_args()`]: Self::read_args
48 /// [`read_options()`]: Self::read_options
49 type Args<'a>;
50
51 /// Read `Self` from the reader using default arguments.
52 ///
53 /// # Errors
54 ///
55 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
56 #[inline]
57 fn read<R: Read + Seek>(reader: &mut R) -> BinResult<Self>
58 where
59 Self: ReadEndian,
60 for<'a> Self::Args<'a>: Required,
61 {
62 Self::read_args(reader, Self::Args::args())
63 }
64
65 /// Read `Self` from the reader using default arguments and assuming
66 /// big-endian byte order.
67 ///
68 /// # Errors
69 ///
70 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
71 #[inline]
72 fn read_be<R: Read + Seek>(reader: &mut R) -> BinResult<Self>
73 where
74 for<'a> Self::Args<'a>: Required,
75 {
76 Self::read_be_args(reader, Self::Args::args())
77 }
78
79 /// Read `Self` from the reader using default arguments and assuming
80 /// little-endian byte order.
81 ///
82 /// # Errors
83 ///
84 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
85 #[inline]
86 fn read_le<R: Read + Seek>(reader: &mut R) -> BinResult<Self>
87 where
88 for<'a> Self::Args<'a>: Required,
89 {
90 Self::read_le_args(reader, Self::Args::args())
91 }
92
93 /// Read `T` from the reader assuming native-endian byte order.
94 ///
95 /// # Errors
96 ///
97 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
98 #[inline]
99 fn read_ne<R: Read + Seek>(reader: &mut R) -> BinResult<Self>
100 where
101 for<'a> Self::Args<'a>: Required,
102 {
103 Self::read_ne_args(reader, Self::Args::args())
104 }
105
106 /// Read `Self` from the reader using the given arguments.
107 ///
108 /// # Errors
109 ///
110 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
111 #[inline]
112 fn read_args<R: Read + Seek>(reader: &mut R, args: Self::Args<'_>) -> BinResult<Self>
113 where
114 Self: ReadEndian,
115 {
116 Self::read_options(reader, Endian::Little, args)
117 }
118
119 /// Read `Self` from the reader, assuming big-endian byte order, using the
120 /// given arguments.
121 ///
122 /// # Errors
123 ///
124 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
125 #[inline]
126 fn read_be_args<R: Read + Seek>(reader: &mut R, args: Self::Args<'_>) -> BinResult<Self> {
127 Self::read_options(reader, Endian::Big, args)
128 }
129
130 /// Read `Self` from the reader, assuming little-endian byte order, using
131 /// the given arguments.
132 ///
133 /// # Errors
134 ///
135 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
136 #[inline]
137 fn read_le_args<R: Read + Seek>(reader: &mut R, args: Self::Args<'_>) -> BinResult<Self> {
138 Self::read_options(reader, Endian::Little, args)
139 }
140
141 /// Read `T` from the reader, assuming native-endian byte order, using the
142 /// given arguments.
143 ///
144 /// # Errors
145 ///
146 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
147 #[inline]
148 fn read_ne_args<R: Read + Seek>(reader: &mut R, args: Self::Args<'_>) -> BinResult<Self> {
149 Self::read_options(reader, Endian::NATIVE, args)
150 }
151
152 /// Read `Self` from the reader using the given [`Endian`] and
153 /// arguments.
154 ///
155 /// # Errors
156 ///
157 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
158 ///
159 /// # Examples
160 ///
161 /// ```
162 /// # use binrw::{BinRead, BinResult};
163 /// # use binrw::io::{Read, Seek, SeekFrom};
164 /// struct CustomPtr32<T>(T);
165 ///
166 /// impl<T> BinRead for CustomPtr32<T>
167 /// where
168 /// for<'a> T: BinRead<Args<'a> = ()>,
169 /// {
170 /// type Args<'a> = u64;
171 ///
172 /// fn read_options<R: Read + Seek>(
173 /// reader: &mut R,
174 /// endian: binrw::Endian,
175 /// args: Self::Args<'_>,
176 /// ) -> BinResult<Self> {
177 /// let offset = u32::read_options(reader, endian, ())?;
178 /// let saved_position = reader.stream_position()?;
179 ///
180 /// // Read from an offset with a provided base offset.
181 /// reader.seek(SeekFrom::Start(args + offset as u64))?;
182 /// let value = T::read_options(reader, endian, ())?;
183 ///
184 /// reader.seek(SeekFrom::Start(saved_position))?;
185 ///
186 /// Ok(CustomPtr32(value))
187 /// }
188 /// }
189 /// ```
190 fn read_options<R: Read + Seek>(
191 reader: &mut R,
192 endian: Endian,
193 args: Self::Args<'_>,
194 ) -> BinResult<Self>;
195}
196
197/// Extension methods for reading [`BinRead`] objects directly from a reader.
198///
199/// # Examples
200///
201/// ```
202/// use binrw::{BinReaderExt, Endian, io::Cursor};
203///
204/// let mut reader = Cursor::new(b"\x07\0\0\0\xCC\0\0\x05");
205/// let x: u32 = reader.read_le().unwrap();
206/// let y: u16 = reader.read_type(Endian::Little).unwrap();
207/// let z = reader.read_be::<u16>().unwrap();
208///
209/// assert_eq!((x, y, z), (7u32, 0xCCu16, 5u16));
210/// ```
211pub trait BinReaderExt: Read + Seek + Sized {
212 /// Read `T` from the reader with the given byte order.
213 ///
214 /// # Errors
215 ///
216 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
217 #[inline]
218 fn read_type<'a, T>(&mut self, endian: Endian) -> BinResult<T>
219 where
220 T: BinRead,
221 T::Args<'a>: Required,
222 {
223 self.read_type_args(endian, T::Args::args())
224 }
225
226 /// Read `T` from the reader assuming big-endian byte order.
227 ///
228 /// # Errors
229 ///
230 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
231 #[inline]
232 fn read_be<'a, T>(&mut self) -> BinResult<T>
233 where
234 T: BinRead,
235 T::Args<'a>: Required,
236 {
237 self.read_type(Endian::Big)
238 }
239
240 /// Read `T` from the reader assuming little-endian byte order.
241 ///
242 /// # Errors
243 ///
244 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
245 #[inline]
246 fn read_le<'a, T>(&mut self) -> BinResult<T>
247 where
248 T: BinRead,
249 T::Args<'a>: Required,
250 {
251 self.read_type(Endian::Little)
252 }
253
254 /// Read `T` from the reader assuming native-endian byte order.
255 ///
256 /// # Errors
257 ///
258 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
259 #[inline]
260 fn read_ne<'a, T>(&mut self) -> BinResult<T>
261 where
262 T: BinRead,
263 T::Args<'a>: Required,
264 {
265 self.read_type(Endian::NATIVE)
266 }
267
268 /// Read `T` from the reader with the given byte order and arguments.
269 ///
270 /// # Errors
271 ///
272 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
273 #[inline]
274 fn read_type_args<T>(&mut self, endian: Endian, args: T::Args<'_>) -> BinResult<T>
275 where
276 T: BinRead,
277 {
278 T::read_options(self, endian, args)
279 }
280
281 /// Read `T` from the reader, assuming big-endian byte order, using the
282 /// given arguments.
283 ///
284 /// # Errors
285 ///
286 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
287 #[inline]
288 fn read_be_args<T>(&mut self, args: T::Args<'_>) -> BinResult<T>
289 where
290 T: BinRead,
291 {
292 self.read_type_args(Endian::Big, args)
293 }
294
295 /// Read `T` from the reader, assuming little-endian byte order, using the
296 /// given arguments.
297 ///
298 /// # Errors
299 ///
300 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
301 #[inline]
302 fn read_le_args<T>(&mut self, args: T::Args<'_>) -> BinResult<T>
303 where
304 T: BinRead,
305 {
306 self.read_type_args(Endian::Little, args)
307 }
308
309 /// Read `T` from the reader, assuming native-endian byte order, using the
310 /// given arguments.
311 ///
312 /// # Errors
313 ///
314 /// If reading fails, an [`Error`](crate::Error) variant will be returned.
315 #[inline]
316 fn read_ne_args<T>(&mut self, args: T::Args<'_>) -> BinResult<T>
317 where
318 T: BinRead,
319 {
320 self.read_type_args(Endian::NATIVE, args)
321 }
322}
323
324impl<R: Read + Seek + Sized> BinReaderExt for R {}