binread/
attribute.rs

1//! A documentation-only module for the possible directives used in `#[br]` and
2//! `#[binread]` attributes.
3//!
4//! # List of directives
5//!
6//! | Directive | Supports | Description
7//! |-----------|----------|------------
8//! | [`align_after`](#padding-and-alignment) | field | Aligns the reader to the Nth byte after reading data.
9//! | [`align_before`](#padding-and-alignment) | field | Aligns the reader to the Nth byte before reading data.
10//! | [`args`](#arguments) | struct field, data variant | Passes arguments to another `BinRead` object.
11//! | [`args_tuple`](#arguments) | struct field, data variant | Like `args`, but specifies a tuple containing the arguments.
12//! | [`assert`](#assert) | struct, field, non-unit enum, data variant | Asserts that a condition is true. Can be used multiple times.
13//! | [`big`](#byte-order) | all except unit variant | Sets the byte order to big-endian.
14//! | [`calc`](#calculations) | field | Computes the value of a field instead of reading data.
15//! | [`count`](#count) | field | Sets the length of a vector.
16//! | [`default`](#default) | field | Uses the [`default`](core::default::Default) value for a field instead of reading data.
17//! | [`deref_now`](#postprocessing) | field | An alias for `postprocess_now`.
18//! | [`if`](#conditional-values) | field | Reads data only if a condition is true.
19//! | [`ignore`](#default) | field | An alias for `default`.
20//! | [`import`](#arguments) | struct, non-unit enum, unit-like enum | Defines extra arguments for a struct or enum.
21//! | [`import_tuple`](#arguments) | struct, non-unit enum, unit-like enum | Like `import`, but receives the arguments as a tuple.
22//! | [`is_big`](#byte-order) | field | Conditionally sets the byte order to big-endian.
23//! | [`is_little`](#byte-order) | field | Conditionally set the byte order to little-endian.
24//! | [`little`](#byte-order) | all except unit variant | Sets the byte order to little-endian.
25//! | [`magic`](#magic) | all | Matches a magic number.
26//! | [`map`](#map) | all except unit variant | Maps a read value to a new value. When used on a struct or enum, the map function must return `Self`.
27//! | [`offset`](#offset) | field | Modifies the offset used by a [`FilePtr`](crate::FilePtr).
28//! | [`pad_after`](#padding-and-alignment) | field | Skips N bytes after reading a field.
29//! | [`pad_before`](#padding-and-alignment) | field | Skips N bytes before reading a field.
30//! | [`pad_size_to`](#padding-and-alignment) | field | Ensures the reader is at least N bytes after the starting position for this field.
31//! | [`parse_with`](#custom-parsers) | field | Specifies a custom function for reading a field.
32//! | [`postprocess_now`](#postprocessing) | field | Calls [`after_parse`](crate::BinRead::after_parse) immediately after reading data instead of after all fields have been read.
33//! | [`pre_assert`](#pre-assert) | struct, non-unit enum, unit variant | Like `assert`, but checks the condition before parsing.
34//! | [`repr`](#repr) | unit-like enum | Specifies the underlying type for a unit-like (C-style) enum.
35//! | [`restore_position`](#restore-position) | field | Restores the reader’s position after reading a field.
36//! | [`return_all_errors`](#enum-errors) | non-unit enum | Returns a [`Vec`] containing the error which occurred on each variant of an enum on failure. This is the default.
37//! | [`return_unexpected_error`](#enum-errors) | non-unit enum | Returns a single generic error on failure.
38//! | [`seek_before`](#padding-and-alignment) | field | Moves the reader to a specific position before reading data.
39//! | [`temp`](#temp) | field | Uses a field as a temporary variable. Only usable with the [`derive_binread`] attribute macro.
40//! | [`try`](#try) | field | Reads data into an [`Option`](core::option::Option), but stores `None` if parsing fails instead of returning an error.
41//! | [`try_map`](#map) | all except unit variant | Like `map`, but returns a [`BinResult`](crate::BinResult).
42//!
43//! # Byte order
44//!
45//! The `big` and `little` directives specify the [byte order](https://en.wikipedia.org/wiki/Endianness)
46//! of data in a struct, enum, variant, or field:
47//!
48//! ```text
49//! #[br(big)]
50//! #[br(little)]
51//! ```
52//!
53//! The `is_big` and `is_little` directives conditionally set the byte order of
54//! a struct field:
55//!
56//! ```text
57//! #[br(is_little = $cond:expr)] or #[br(is_little($cond:expr))]
58//! #[br(is_big = $cond:expr)] or #[br(is_big($cond:expr))]
59//! ```
60//!
61//! The `is_big` and `is_little` directives are primarily useful when byte order
62//! is defined in the data itself. Any earlier field or [import](#arguments) can
63//! be referenced in the condition. Conditional byte order directives can only
64//! be used on struct fields.
65//!
66//! The order of precedence (from highest to lowest) for determining byte order
67//! within an object is:
68//!
69//! 1. A directive on a field
70//! 2. A directive on an enum variant
71//! 3. A directive on the struct or enum
72//! 4. The [`endian`](crate::ReadOptions::endian) property of the
73//!    [`ReadOptions`](crate::ReadOptions) object passed to
74//!    [`BinRead::read_options`](crate::BinRead::read_options) by the caller
75//! 5. The host machine’s native byte order
76//!
77//! However, if a byte order directive is added to a struct or enum, that byte
78//! order will *always* be used, even if the object is embedded in another
79//! object or explicitly called with a different byte order:
80//!
81//! ```
82//! # use binread::{Endian, ReadOptions, prelude::*, io::Cursor};
83//! #[derive(BinRead, Debug, PartialEq)]
84//! #[br(little)] // ← this *forces* the struct to be little-endian
85//! struct Child(u32);
86//!
87//! #[derive(BinRead, Debug)]
88//! struct Parent {
89//!     #[br(big)] // ← this will be ignored
90//!     child: Child,
91//! };
92//!
93//! let mut options = ReadOptions::default();
94//! options.endian = Endian::Big; // ← this will be ignored
95//! # assert_eq!(
96//! Child::read_options(&mut Cursor::new(b"\x01\0\0\0"), &options, ())
97//! # .unwrap(), Child(1));
98//! ```
99//!
100//! When manually implementing
101//! [`BinRead::read_options`](crate::BinRead::read_options) or a
102//! [custom parser function](#custom-parsers), the byte order is accessible
103//! from [`ReadOptions::endian`](crate::ReadOptions::endian).
104//!
105//! ## Examples
106//!
107//! ```
108//! # use binread::{prelude::*, io::Cursor};
109//! #[derive(BinRead)]
110//! #[br(little)]
111//! struct MyType (
112//!     #[br(big)] u32, // ← will be big-endian
113//!     u32, // ← will be little-endian
114//! );
115//! ```
116//!
117//! ```
118//! # use binread::{prelude::*, io::Cursor};
119//! #[derive(BinRead, Debug, PartialEq)]
120//! #[br(big)]
121//! struct MyType {
122//!     val: u8,
123//!     #[br(is_little = (val == 3))]
124//!     other_val: u16 // ← little-endian if `val == 3`, otherwise big-endian
125//! }
126//!
127//! # assert_eq!(MyType::read(&mut Cursor::new(b"\x03\x01\x00")).unwrap(), MyType { val: 3, other_val: 1 });
128//! ```
129//!
130//! # Magic
131//!
132//! The `magic` directive matches [magic numbers](https://en.wikipedia.org/wiki/Magic_number_(programming))
133//! in data:
134//!
135//! ```text
136//! #[br(magic = $magic:literal)] or #[br(magic($magic:literal))]
137//! ```
138//!
139//! The magic number can be a byte literal, byte string, char, float, or
140//! integer. When a magic number is matched, parsing begins with the first byte
141//! after the magic number in the data. When a magic number is not matched, an
142//! error is returned.
143//!
144//! ## Examples
145//!
146//! ```
147//! # use binread::{prelude::*, io::Cursor};
148//! #[derive(BinRead, Debug)]
149//! #[br(magic = b"TEST")]
150//! struct Test {
151//!     val: u32
152//! }
153//!
154//! #[derive(BinRead, Debug)]
155//! #[br(magic = 1.2f32)]
156//! struct Version(u16);
157//!
158//! #[derive(BinRead)]
159//! enum Command {
160//!     #[br(magic = 0u8)] Nop,
161//!     #[br(magic = 1u8)] Jump { loc: u32 },
162//!     #[br(magic = 2u8)] Begin { var_count: u16, local_count: u16 }
163//! }
164//! ```
165//!
166//! ## Errors
167//!
168//! If the specified magic number does not match the data, a
169//! [`BadMagic`](crate::Error::BadMagic) error is returned and the reader’s
170//! position is reset to where it was before parsing started.
171//!
172//! # Assert
173//!
174//! The `assert` directive validates objects and fields after they are read,
175//! returning an error if the assertion condition evaluates to `false`:
176//!
177//! ```text
178//! #[br(assert($cond:expr $(,)?))]
179//! #[br(assert($cond:expr, $msg:literal $(,)?)]
180//! #[br(assert($cond:expr, $fmt:literal, $($arg:expr),* $(,)?))]
181//! #[br(assert($cond:expr, $err:expr $(,)?)]
182//! ```
183//!
184//! Multiple assertion directives can be used; they will be combined and
185//! executed in order.
186//!
187//! Assertions added to the top of an enum will be checked against every variant
188//! in the enum.
189//!
190//! Any earlier field or [import](#arguments) can be referenced by expressions
191//! in the directive.
192//!
193//! ## Examples
194//!
195//! ### Formatted error
196//!
197//! ```rust
198//! # use binread::{prelude::*, io::Cursor};
199//! #[derive(Debug, PartialEq)]
200//! struct NotSmallerError(u32, u32);
201//!
202//! #[derive(BinRead, Debug)]
203//! #[br(assert(some_val > some_smaller_val, "oops! {} <= {}", some_val, some_smaller_val))]
204//! struct Test {
205//!     some_val: u32,
206//!     some_smaller_val: u32
207//! }
208//!
209//! let error = Cursor::new(b"\0\0\0\x01\0\0\0\xFF").read_be::<Test>();
210//! assert!(error.is_err());
211//! let error = error.unwrap_err();
212//! let expected = "oops! 1 <= 255".to_string();
213//! assert!(matches!(error, binread::Error::AssertFail { message: expected, .. }));
214//! ```
215//!
216//! ### Custom error
217//!
218//! ```rust
219//! # use binread::{prelude::*, io::Cursor};
220//! #[derive(Debug, PartialEq)]
221//! struct NotSmallerError(u32, u32);
222//!
223//! #[derive(BinRead, Debug)]
224//! #[br(assert(some_val > some_smaller_val, NotSmallerError(some_val, some_smaller_val)))]
225//! struct Test {
226//!     some_val: u32,
227//!     some_smaller_val: u32
228//! }
229//!
230//! let error = Cursor::new(b"\0\0\0\x01\0\0\0\xFF").read_be::<Test>();
231//! assert!(error.is_err());
232//! let error = error.unwrap_err();
233//! assert_eq!(error.custom_err(), Some(&NotSmallerError(0x1, 0xFF)));
234//! ```
235//!
236//! ## Errors
237//!
238//! If the assertion fails and there is no second argument, or a string literal
239//! is given as the second argument, an [`AssertFail`](crate::Error::AssertFail)
240//! error is returned.
241//!
242//! If the assertion fails and an expression is given as the second argument,
243//! a [`Custom`](crate::Error::Custom) error containing the result of the
244//! expression is returned.
245//!
246//! Arguments other than the condition are not evaluated unless the assertion
247//! fails, so it is safe for them to contain expensive operations without
248//! impacting performance.
249//!
250//! In all cases, the reader’s position is reset to where it was before parsing
251//! started.
252//!
253//! # Pre-assert
254//!
255//! `pre_assert` works like [`assert`](#assert), but checks the condition before
256//! data is read instead of after. This is most useful when validating arguments
257//! or choosing an enum variant to parse.
258//!
259//! ```text
260//! #[br(pre_assert($cond:expr $(,)?))]
261//! #[br(pre_assert($cond:expr, $msg:literal $(,)?)]
262//! #[br(pre_assert($cond:expr, $fmt:literal, $($arg:expr),* $(,)?))]
263//! #[br(pre_assert($cond:expr, $err:expr $(,)?)]
264//! ```
265//!
266//! ## Examples
267//!
268//! ```
269//! # use binread::{prelude::*, io::Cursor};
270//! #[derive(BinRead, Debug, PartialEq)]
271//! #[br(import(ty: u8))]
272//! enum Command {
273//!     #[br(pre_assert(ty == 0))] Variant0(u16, u16),
274//!     #[br(pre_assert(ty == 1))] Variant1(u32)
275//! }
276//!
277//! #[derive(BinRead, Debug, PartialEq)]
278//! struct Message {
279//!     ty: u8,
280//!     len: u8,
281//!     #[br(args(ty))]
282//!     data: Command
283//! }
284//!
285//! let msg = Cursor::new(b"\x01\x04\0\0\0\xFF").read_be::<Message>();
286//! assert!(msg.is_ok());
287//! let msg = msg.unwrap();
288//! assert_eq!(msg, Message { ty: 1, len: 4, data: Command::Variant1(0xFF) });
289//! ```
290//!
291//! # Arguments
292//!
293//! The `import` and `args` directives define the type of
294//! [`BinRead::Args`](crate::BinRead::Args) and the values passed in the `args`
295//! argument of a [`BinRead::read_options`](crate::BinRead::read_options) call,
296//! respectively:
297//!
298//! ```text
299//! #[br(import($($ident:ident : $ty:ty),* $(,)?))]
300//! #[br(args($($ident:ident),* $(,)?))]
301//! ```
302//!
303//! Any earlier field or [import](#arguments) can be referenced in `args`.
304//!
305//! ## Examples
306//!
307//! ```
308//! # use binread::prelude::*;
309//! #[derive(BinRead)]
310//! #[br(import(val1: u32, val2: &'static str))]
311//! struct ImportTest {
312//!     // ...
313//! }
314//!
315//! #[derive(BinRead)]
316//! struct ArgsTets {
317//!     val: u32,
318//!     #[br(args(val + 3, "test"))]
319//!     test: ImportTest
320//! }
321//! ```
322//!
323//! # Default
324//!
325//! The `default` directive, and its alias `ignore`, sets the value of the field
326//! to its [`Default`](core::default::Default) instead of reading data from the
327//! reader:
328//!
329//! ```text
330//! #[br(default)] or #[br(ignore)]
331//! ```
332//!
333//! ## Examples
334//!
335//! ```rust
336//! # use binread::{BinRead, io::Cursor};
337//! #[derive(BinRead, Debug, PartialEq)]
338//! struct Test {
339//!     #[br(default)]
340//!     path: Option<std::path::PathBuf>,
341//! }
342//!
343//! assert_eq!(
344//!     Test::read(&mut Cursor::new(b"")).unwrap(),
345//!     Test { path: None }
346//! );
347//! ```
348//!
349//! # Temp
350//!
351//! **This directive can only be used with [`derive_binread`]. It will not work
352//! with `#[derive(BinRead)]`.**
353//!
354//! The `temp` directive causes a field to be treated as a temporary variable
355//! instead of an actual field. The field will be removed from the struct
356//! definition generated by [`derive_binread`]:
357//!
358//! ```text
359//! #[br(temp)]
360//! ```
361//!
362//! This allows data to be read which is necessary for parsing an object but
363//! which doesn’t need to be stored in the final object. To skip data, entirely
364//! use an [alignment directive](#padding-and-alignment) instead.
365//!
366//! ## Examples
367//!
368//! ```rust
369//! # use binread::{BinRead, io::Cursor, derive_binread};
370//! #[derive_binread]
371//! #[derive(Debug, PartialEq)]
372//! struct Test {
373//!     // Since `Vec` stores its own length, this field is redundant
374//!     #[br(temp, big)]
375//!     len: u32,
376//!
377//!     #[br(count = len)]
378//!     data: Vec<u8>
379//! }
380//!
381//! assert_eq!(
382//!     Test::read(&mut Cursor::new(b"\0\0\0\x05ABCDE")).unwrap(),
383//!     Test { data: Vec::from(&b"ABCDE"[..]) }
384//! );
385//! ```
386//!
387//! # Postprocessing
388//!
389//! The `deref_now` directive, and its alias `postprocess_now`, cause a
390//! field’s [`after_parse`](crate::BinRead::after_parse) function to be called
391//! immediately after the field is parsed, instead of deferring the call until
392//! the entire parent object has been parsed:
393//!
394//! ```text
395//! #[br(deref_now)] or #[br(postprocess_now)]
396//! ```
397//!
398//! The [`BinRead::after_parse`](crate::BinRead::after_parse) function is
399//! normally used to perform additional work after the whole parent object has
400//! been parsed. For example, the [`FilePtr`](crate::FilePtr) type reads an
401//! object offset during parsing with
402//! [`read_options`](crate::BinRead::read_options), then actually seeks to and
403//! parses the pointed-to object in `after_parse`. This improves read
404//! performance by reading the whole parent object sequentially before seeking
405//! to read the pointed-to object.
406//!
407//! However, if another field in the parent object needs to access data from the
408//! pointed-to object, `after_parse` needs to be called earlier. Adding
409//! `deref_now` (or its alias, `postprocess_now`) to the earlier field causes
410//! this to happen.
411//!
412//! ## Examples
413//!
414//! ```
415//! # use binread::{prelude::*, FilePtr32, NullString, io::Cursor};
416//! #[derive(BinRead, Debug)]
417//! #[br(big, magic = b"TEST")]
418//! struct TestFile {
419//!     #[br(deref_now)]
420//!     ptr: FilePtr32<NullString>,
421//!
422//!     value: i32,
423//!
424//!     // Notice how `ptr` can be used as it has already been postprocessed
425//!     #[br(calc = ptr.len())]
426//!     ptr_len: usize,
427//! }
428//!
429//! # let test_contents = b"\x54\x45\x53\x54\x00\x00\x00\x10\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x54\x65\x73\x74\x20\x73\x74\x72\x69\x6E\x67\x00\x00\x00\x00\x69";
430//! # let test = Cursor::new(test_contents).read_be::<TestFile>().unwrap();
431//! # assert_eq!(test.ptr_len, 11);
432//! # assert_eq!(test.value, -1);
433//! # assert_eq!(test.ptr.to_string(), "Test string");
434//! ```
435//!
436//! # Restore position
437//!
438//! The `restore_position` directive restores the position of the reader after
439//! a field is read:
440//!
441//! ```text
442//! #[br(restore_position)]
443//! ```
444//!
445//! To seek to an arbitrary position, use [`seek_before`](#padding-and-alignment)
446//! instead.
447//!
448//! ## Examples
449//!
450//! ```
451//! # use binread::{prelude::*, io::Cursor};
452//! #[derive(BinRead, Debug, PartialEq)]
453//! struct MyType {
454//!     #[br(restore_position)]
455//!     test: u32,
456//!     test_bytes: [u8; 4]
457//! }
458//!
459//! # assert_eq!(
460//! #   Cursor::new(b"\0\0\0\x01").read_be::<MyType>().unwrap(),
461//! #   MyType { test: 1, test_bytes: [0,0,0,1]}
462//! # );
463//! ```
464//!
465//! ## Errors
466//!
467//! If querying or restoring the reader position fails, an
468//! [`Io`](crate::Error::Io) error is returned and the reader’s
469//! position is reset to where it was before parsing started.
470//!
471//! # Try
472//!
473//! The `try` directive allows parsing of an [`Option`] field to fail instead
474//! of returning an error:
475//!
476//! ```text
477//! #[br(try)]
478//! ```
479//!
480//! If the field cannot be parsed, the position of the reader will be restored
481//! and the value of the field will be set to [`None`].
482//!
483//! ## Examples
484//!
485//! ```
486//! # use binread::{prelude::*, io::Cursor};
487//! #[derive(BinRead)]
488//! struct MyType {
489//!     #[br(try)]
490//!     maybe_u32: Option<u32>
491//! }
492//!
493//! assert_eq!(Cursor::new(b"").read_be::<MyType>().unwrap().maybe_u32, None);
494//! ```
495//!
496//! # Map
497//!
498//! The `map` and `try_map` directives allow data to be read using one type and
499//! stored as another:
500//!
501//! ```text
502//! #[br(map = $map_fn:expr)] or #[map($map_fn:expr))]
503//! #[br(try_map = $map_fn:expr)] or #[try_map($map_fn:expr))]
504//! ```
505//!
506//! When using `map` on a field, the map function must explicitly declare the
507//! type of the data to be read in its first parameter and return a value which
508//! matches the type of the field. The map function can be a plain function,
509//! closure, or call expression which returns a plain function or closure.
510//!
511//! When using `try_map` on a field, the same rules apply, except that the
512//! function must return a [`Result`] instead.
513//!
514//! When using `map` or `try_map` on a struct or enum, the map function must
515//! return `Self` or `Result<Self, E>`.
516//!
517//! Any earlier field or [import](#arguments) can be referenced by the
518//! expression in the directive.
519//!
520//! ## Examples
521//!
522//! ### Using `map` on a field
523//!
524//! ```
525//! # use binread::{prelude::*, io::Cursor};
526//! #[derive(BinRead)]
527//! struct MyType {
528//!     #[br(map = |x: u8| x.to_string())]
529//!     int_str: String
530//! }
531//!
532//! # assert_eq!(Cursor::new(b"\0").read_be::<MyType>().unwrap().int_str, "0");
533//! ```
534//!
535//! ### Using `try_map` on a field
536//!
537//! ```
538//! # use binread::{prelude::*, io::Cursor};
539//! # use std::convert::TryInto;
540//! #[derive(BinRead)]
541//! struct MyType {
542//!     #[br(try_map = |x: i8| x.try_into())]
543//!     value: u8
544//! }
545//!
546//! # assert_eq!(Cursor::new(b"\0").read_be::<MyType>().unwrap().value, 0);
547//! # assert!(Cursor::new(b"\xff").read_be::<MyType>().is_err());
548//! ```
549//!
550//! ### Using `map` on a struct to create a bit field
551//!
552//! The [`modular-bitfield`](https://docs.rs/modular-bitfield) crate can be used
553//! along with `map` to create a struct out of raw bits.
554//!
555//! ```
556//! # use binread::{prelude::*, io::Cursor};
557//! use modular_bitfield::prelude::*;
558//!
559//! // This reads a single byte from the reader
560//! #[bitfield]
561//! #[derive(BinRead)]
562//! #[br(map = Self::from_bytes)]
563//! pub struct PackedData {
564//!     status: B4,
565//!     is_fast: bool,
566//!     is_static: bool,
567//!     is_alive: bool,
568//!     is_good: bool,
569//! }
570//!
571//! // example byte: 0x53
572//! // [good] [alive] [static] [fast] [status]
573//! //      0       1        0      1     0011
574//! //  false    true    false   true        3
575//!
576//! # let data = Cursor::new(b"\x53").read_le::<PackedData>().unwrap();
577//! # assert_eq!(data.is_good(), false);
578//! # assert_eq!(data.is_alive(), true);
579//! # assert_eq!(data.is_static(), false);
580//! # assert_eq!(data.is_fast(), true);
581//! # assert_eq!(data.status(), 3);
582//! ```
583//!
584//! ## Errors
585//!
586//! If the `try_map` function returns a [`binread::io::Error`](crate::io::Error)
587//! or [`std::io::Error`], an [`Io`](crate::Error::Io) error is returned. For
588//! any other error type, a [`Custom`](crate::Error::Custom) error is returned.
589//!
590//! In all cases, the reader’s position is reset to where it was before parsing
591//! started.
592//!
593//! # Custom parsers
594//!
595//! The `parse_with` directive specifies a custom parsing function which can be
596//! used to override the default [`BinRead`](crate::BinRead) implementation for
597//! a type, or to parse types which have no `BinRead` implementation at all:
598//!
599//! ```text
600//! #[br(parse_with = $parse_fn:expr)] or #[br(parse_with($parse_fn:expr))]
601//! ```
602//!
603//! Any earlier field or [import](#arguments) can be referenced by the
604//! expression in the directive (for example, to construct a parser function at
605//! runtime by calling a function generator).
606//!
607//! ## Examples
608//!
609//! ### Using a custom parser to generate a [`HashMap`](std::collections::HashMap)
610//!
611//! ```
612//! # use binread::{prelude::*, io::*, ReadOptions};
613//! # use std::collections::HashMap;
614//! fn custom_parser<R: Read + Seek>(reader: &mut R, ro: &ReadOptions, _: ())
615//!     -> BinResult<HashMap<u16, u16>>
616//! {
617//!     let mut map = HashMap::new();
618//!     map.insert(
619//!         reader.read_be().unwrap(),
620//!         reader.read_be().unwrap()
621//!     );
622//!     Ok(map)
623//! }
624//!
625//! #[derive(BinRead)]
626//! struct MyType {
627//!     #[br(parse_with = custom_parser)]
628//!     offsets: HashMap<u16, u16>
629//! }
630//!
631//! # assert_eq!(Cursor::new(b"\0\0\0\x01").read_be::<MyType>().unwrap().offsets.get(&0), Some(&1));
632//! ```
633//!
634//! ### Using `FilePtr::parse` to read a `NullString` without storing a `FilePtr`
635//!
636//! ```
637//! # use binread::{prelude::*, io::Cursor, FilePtr32, NullString};
638//! #[derive(BinRead)]
639//! struct MyType {
640//!     #[br(parse_with = FilePtr32::parse)]
641//!     some_string: NullString,
642//! }
643//!
644//! # let val: MyType = Cursor::new(b"\0\0\0\x04Test\0").read_be().unwrap();
645//! # assert_eq!(val.some_string.to_string(), "Test");
646//! ```
647//!
648//! # Calculations
649//!
650//! The `calc` directive computes the value of a field instead of reading data
651//! from the reader:
652//!
653//! ```text
654//! #[br(calc = $value:expr)] or #[br(calc($value:expr))]
655//! ```
656//!
657//! Any earlier field or [import](#arguments) can be referenced by the
658//! expression in the directive.
659//!
660//! ## Examples
661//!
662//! ```rust
663//! # use binread::{prelude::*, io::Cursor};
664//! #[derive(BinRead)]
665//! struct MyType {
666//!     var: u32,
667//!     #[br(calc = 3 + var)]
668//!     var_plus_3: u32,
669//! }
670//!
671//! # assert_eq!(Cursor::new(b"\0\0\0\x01").read_be::<MyType>().unwrap().var_plus_3, 4);
672//! ```
673//!
674//! # Count
675//!
676//! The `count` directive sets the number of values to read into a repeating
677//! collection type like a [`Vec`]:
678//!
679//! ```text
680//! #[br(count = $count:expr) or #[br(count($count:expr))]
681//! ```
682//!
683//! When manually implementing
684//! [`BinRead::read_options`](crate::BinRead::read_options) or a
685//! [custom parser function](#custom-parsers), the `count` value is accessible
686//! from [`ReadOptions::count`](crate::ReadOptions::count).
687//!
688//! Any earlier field or [import](#arguments) can be referenced by the
689//! expression in the directive.
690//!
691//! ## Examples
692//!
693//! ### Using `count` with [`Vec`]
694//!
695//! ```
696//! # use binread::{prelude::*, io::Cursor};
697//! #[derive(BinRead)]
698//! struct MyType {
699//!     size: u32,
700//!     #[br(count = size)]
701//!     data: Vec<u8>,
702//! }
703//!
704//! # assert_eq!(
705//! #    Cursor::new(b"\0\0\0\x04\x01\x02\x03\x04").read_be::<MyType>().unwrap().data,
706//! #    &[1u8, 2, 3, 4]
707//! # );
708//! ```
709//!
710//! ### Using `count` with [`FilePtr`](crate::FilePtr) and `Vec`
711//!
712//! ```
713//! # use binread::{prelude::*, io::Cursor, FilePtr};
714//! #[derive(BinRead)]
715//! struct MyType {
716//!     size: u32,
717//!     #[br(count = size)]
718//!     data: FilePtr<u32, Vec<u8>>,
719//! }
720//!
721//! # assert_eq!(
722//! #    *(Cursor::new(b"\0\0\0\x04\0\0\0\x09\0\x01\x02\x03\x04").read_be::<MyType>().unwrap().data),
723//! #    &[1u8, 2, 3, 4]
724//! # );
725//! ```
726//!
727//! # Offset
728//!
729//! The `offset` and `offset_after` directives specify an additional relative
730//! offset to a value accessed by a `BinRead` implementation which reads data
731//! from an offset, like [`FilePtr`](crate::FilePtr):
732//!
733//! ```text
734//! #[br(offset = $offset:expr)] or #[br(offset($offset:expr))]
735//! #[br(offset_after = $offset:expr)] or #[br(offset_after($offset:expr))]
736//! ```
737//!
738//! When manually implementing
739//! [`BinRead::read_options`](crate::BinRead::read_options) or a
740//! [custom parser function](#custom-parsers), the offset is accessible
741//! from [`ReadOptions::offset`](crate::ReadOptions::offset).
742//!
743//! For `offset`, any earlier field or [import](#arguments) can be referenced by
744//! the expression in the directive.
745//!
746//! For `offset_after`, *all* fields and imports can be referenced by the
747//! expression in the directive, but [`deref_now`](#postprocessing) cannot be
748//! used.
749//!
750//! ## Examples
751//!
752//! ```rust
753//! # use binread::{prelude::*, io::Cursor, FilePtr};
754//! #[derive(BinRead, Debug, PartialEq)]
755//! struct OffsetTest {
756//!     #[br(little, offset = 4)]
757//!     test: FilePtr<u8, u16>
758//! }
759//!
760//! # assert_eq!(
761//! #   *OffsetTest::read(&mut Cursor::new(b"\0\xFF\xFF\xFF\x02\0")).unwrap().test,
762//! #   2u16
763//! # );
764//! ```
765//!
766//! ## Errors
767//!
768//! If seeking to or reading from the offset fails, an [`Io`](crate::Error::Io)
769//! error is returned and the reader’s position is reset to where it was before
770//! parsing started.
771//!
772//! # Conditional values
773//!
774//! The `if` directive allows conditional parsing of a field, reading from data
775//! if the condition is true and using a computed value if the condition is
776//! false:
777//!
778//! ```text
779//! #[br(if = $cond:expr)] or #[br(if($cond:expr))]
780//! #[br(if = $cond:expr, $alternate:expr)] or #[br(if($cond:expr, $alternate:expr))]
781//! ```
782//!
783//! If an alternate is provided, that value will be used when the condition is
784//! false; otherwise, the [`default`](core::default::Default) value for the type
785//! will be used.
786//!
787//! The alternate expression is not evaluated unless the condition is false, so
788//! it is safe for it to contain expensive operations without impacting
789//! performance.
790//!
791//! Any earlier field or [import](#arguments) can be referenced by the
792//! expression in the directive.
793//!
794//! ## Examples
795//!
796//! ### Using an [`Option`] field with no alternate
797//!
798//! ```rust
799//! # use binread::{prelude::*, io::Cursor};
800//! #[derive(BinRead)]
801//! struct MyType {
802//!     var: u32,
803//!
804//!     #[br(if(var == 1))]
805//!     original_byte: Option<u8>,
806//!
807//!     #[br(if(var != 1))]
808//!     other_byte: Option<u8>,
809//! }
810//!
811//! # assert_eq!(Cursor::new(b"\0\0\0\x01\x03").read_be::<MyType>().unwrap().original_byte, Some(3));
812//! # assert_eq!(Cursor::new(b"\0\0\0\x01\x03").read_be::<MyType>().unwrap().other_byte, None);
813//! ```
814//!
815//! ### Using a scalar field with an explicit alternate
816//!
817//! ```rust
818//! # use binread::{prelude::*, io::Cursor};
819//! #[derive(BinRead)]
820//! struct MyType {
821//!     var: u32,
822//!
823//!     #[br(if(var == 1, 0))]
824//!     original_byte: u8,
825//!
826//!     #[br(if(var != 1, 42))]
827//!     other_byte: u8,
828//! }
829//!
830//! # assert_eq!(Cursor::new(b"\0\0\0\x01\x03").read_be::<MyType>().unwrap().original_byte, 3);
831//! # assert_eq!(Cursor::new(b"\0\0\0\x01\x03").read_be::<MyType>().unwrap().other_byte, 42);
832//! ```
833//!
834//! # Padding and alignment
835//!
836//! BinRead offers different directives for common forms of
837//! [data structure alignment](https://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding).
838//!
839//! The `pad_before` and `pad_after` directives skip a specific number of bytes
840//! either before or after reading a field, respectively:
841//!
842//! ```text
843//! #[br(pad_after = $skip_bytes:expr)] or #[br(pad_after($skip_bytes:expr))]
844//! #[br(pad_before = $skip_bytes:expr)] or #[br(pad_before($skip_bytes:expr))]
845//! ```
846//!
847//! The `align_before` and `align_after` directives align the next read to the
848//! given byte alignment either before or after reading a field, respectively:
849//!
850//! ```text
851//! #[br(align_after = $align_to:expr)] or #[br(align_after($align_to:expr))]
852//! #[br(align_before = $align_to:expr)] or #[br(align_before($align_to:expr))]
853//! ```
854//!
855//! The `seek_before` directive accepts a [`SeekFrom`](crate::io::SeekFrom)
856//! object and seeks the reader to an arbitrary position before reading a field:
857//!
858//! ```text
859//! #[br(seek_before = $seek_from:expr)] or #[br(seek_before($seek_from:expr))]
860//! ```
861//!
862//! The position of the reader will not be restored after the seek; use the
863//! [`restore_position`](#restore-position) directive for this.
864//!
865//! The `pad_size_to` directive will ensure that the reader has advanced at
866//! least the number of bytes given after the field has been read:
867//!
868//! ```text
869//! #[br(pad_size_to = $size:expr)] or #[br(pad_size_to($size:expr))]
870//! ```
871//!
872//! For example, if a format uses a null-terminated string, but always reserves
873//! at least 256 bytes for that string, [`NullString`](crate::NullString) will
874//! read the string and `pad_size_to(256)` will ensure the reader skips whatever
875//! padding, if any, remains. If the string is longer than 256 bytes, no padding
876//! will be skipped.
877//!
878//! Any earlier field or [import](#arguments) can be referenced by the
879//! expressions in any of these directives.
880//!
881//! ## Examples
882//!
883//! ```rust
884//! # use binread::{BinRead, NullString, io::SeekFrom};
885//! #[derive(BinRead)]
886//! struct MyType {
887//!     #[br(align_before = 4, pad_after = 1, align_after = 4)]
888//!     str: NullString,
889//!
890//!     #[br(pad_size_to = 0x10)]
891//!     test: u64,
892//!
893//!     #[br(seek_before = SeekFrom::End(-4))]
894//!     end: u32,
895//! }
896//! ```
897//!
898//! ## Errors
899//!
900//! If seeking fails, an [`Io`](crate::Error::Io) error is returned and the
901//! reader’s position is reset to where it was before parsing started.
902//!
903//! # Repr
904//!
905//! The `repr` directive is used on a unit-like (C-style) enum to specify the
906//! underlying type to use when reading the field and matching variants:
907//!
908//! ```text
909//! #[br(repr = $ty:ty)] or #[br(repr($ty:ty))]
910//! ```
911//!
912//! ## Examples
913//!
914//! ```
915//! # use binread::BinRead;
916//! #[derive(BinRead)]
917//! #[br(big, repr = i16)]
918//! enum FileKind {
919//!     Unknown = -1,
920//!     Text,
921//!     Archive,
922//!     Document,
923//!     Picture,
924//! }
925//! ```
926//!
927//! ## Errors
928//!
929//! If a read fails, an [`Io`](crate::Error::Io) error is returned. If no
930//! variant matches, a [`NoVariantMatch`](crate::Error::NoVariantMatch) error
931//! is returned.
932//!
933//! In all cases, the reader’s position is reset to where it was before parsing
934//! started.
935
936#![allow(unused_imports)]
937
938use crate::derive_binread;