binrw/
lib.rs

1#![doc = include_str!("../doc/index.md")]
2#![cfg_attr(not(feature = "std"), no_std)]
3#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
4#![cfg_attr(all(doc, nightly), feature(doc_cfg))]
5#![warn(clippy::pedantic)]
6#![warn(missing_docs)]
7#![warn(rust_2018_idioms)]
8// Lint: This is not beneficial for code organisation.
9#![allow(clippy::module_name_repetitions)]
10
11extern crate alloc;
12// This extern crate declaration is required to use binrw_derive macros like
13// NamedArgs inside binrw because the generated code references a binrw crate,
14// but binrw is not a dependency of binrw so no crate with that name gets
15// automatically added by cargo to the extern prelude.
16extern crate self as binrw;
17#[cfg(all(doc, not(feature = "std")))]
18extern crate std;
19
20#[doc(hidden)]
21#[path = "private.rs"]
22pub mod __private;
23mod binread;
24mod binwrite;
25pub mod docs;
26pub mod endian;
27pub mod error;
28pub mod file_ptr;
29pub mod helpers;
30pub mod io;
31pub mod meta;
32mod named_args;
33#[doc(hidden)]
34pub mod pos_value;
35pub mod punctuated;
36#[doc(hidden)]
37pub mod strings;
38
39#[cfg(all(doc, not(feature = "std")))]
40use alloc::vec::Vec;
41#[doc(inline)]
42pub use {
43    binread::*,
44    binwrite::*,
45    endian::Endian,
46    error::Error,
47    file_ptr::{FilePtr, FilePtr128, FilePtr16, FilePtr32, FilePtr64, FilePtr8},
48    named_args::NamedArgs,
49    pos_value::PosValue,
50    strings::{NullString, NullWideString},
51};
52
53/// Derive macro generating an impl of the trait [`BinRead`].
54///
55/// See the [directives glossary](docs::attribute) for usage details.
56pub use binrw_derive::BinRead;
57
58/// Attribute macro used to generate an impl of the trait [`BinRead`] with
59/// support for [temporary variables](docs::attribute#temp).
60///
61/// When using temporary variables, this attribute **must** be placed above
62/// other attributes that generate code (e.g. `#[derive(Debug)]`) to ensure that
63/// the deleted temporary fields aren’t visible to those macros.
64///
65/// See the [directives glossary](docs::attribute) for usage details.
66pub use binrw_derive::binread;
67
68/// Derive macro generating an impl of the trait [`BinWrite`].
69///
70/// See the [directives glossary](docs::attribute) for usage details.
71pub use binrw_derive::BinWrite;
72
73/// Attribute macro used to generate an impl of the trait [`BinWrite`] with
74/// support for [temporary variables](docs::attribute#temp).
75///
76/// When using temporary variables, this attribute **must** be placed above
77/// other attributes that generate code (e.g. `#[derive(Debug)]`) to ensure that
78/// the deleted temporary fields aren’t visible to those macros.
79///
80/// See the [directives glossary](docs::attribute) for usage details.
81pub use binrw_derive::binwrite;
82
83/// Attribute macro used to generate an impl of both [`BinRead`] and
84/// [`BinWrite`] traits with support for
85/// [temporary variables](docs::attribute#temp).
86///
87/// When using temporary variables, this attribute **must** be placed above
88/// other attributes that generate code (e.g. `#[derive(Debug)]`) to ensure that
89/// the deleted temporary fields aren’t visible to those macros.
90///
91/// See the [directives glossary](docs::attribute) for usage details.
92pub use binrw_derive::binrw;
93
94/// Derive macro generating an impl of the trait [`NamedArgs`].
95///
96/// The use cases for this macro are:
97///
98/// 1. When manually implementing [`BinRead`] or [`BinWrite`] on a type where
99///    named arguments are desired.
100/// 2. When creating a
101///    [custom parser or writer](docs::attribute#custom-parserswriters)
102///    where named arguments are desired.
103/// 3. When a named arguments type should be shared by several different types
104///    (e.g. by using [`import_raw`](docs::attribute#raw-arguments) on
105///    derived types, and by assigning the type to [`BinRead::Args`] or
106///    [`BinWrite::Args`] in manual implementations).
107///
108/// # Field options
109///
110/// * `#[named_args(default = $expr)]`: Sets the default value for a field.
111///
112/// # Examples
113///
114/// ```
115/// use binrw::{args, binread, BinRead, NamedArgs};
116/// #[derive(Clone, NamedArgs)]
117/// struct GlobalArgs<Inner> {
118///     #[named_args(default = 1)]
119///     version: i16,
120///     inner: Inner,
121/// }
122///
123/// #[binread]
124/// #[br(import_raw(args: GlobalArgs<T::Args<'_>>))]
125/// struct Container<T>
126/// where
127///     T: BinRead + 'static,
128///     for<'a> T::Args<'a>: Clone,
129/// {
130///     #[br(temp, if(args.version > 1, 16))]
131///     count: u16,
132///     #[br(args {
133///         count: count.into(),
134///         inner: args.inner
135///     })]
136///     items: Vec<T>,
137/// }
138///
139/// # let mut input = binrw::io::Cursor::new(b"\x02\0\x42\0\x69\0");
140/// # assert_eq!(
141/// #     Container::<u16>::read_le_args(&mut input, args! { version: 2, inner: () }).unwrap().items,
142/// #     vec![0x42, 0x69]
143/// # );
144/// ```
145pub use binrw_derive::NamedArgs;
146
147/// Attribute macro used to generate
148/// [`parse_with`](docs::attribute#custom-parserswriters) functions.
149///
150/// Rust functions are transformed by this macro to match the binrw API.
151///
152/// # Attribute options
153///
154/// * `#[parser(reader)]` or `#[parser(reader: $ident)]`: Exposes the write
155///   stream to the function. If no variable name is given, `reader` is used.
156/// * `#[parser(endian)]` or `#[parser(endian: $ident)]`: Exposes the endianness
157///   to the function. If no variable name is given, `endian` is used.
158///
159/// Options are comma-separated.
160///
161/// # Function parameters
162///
163/// Parameters are transformed into either
164/// [tuple-style arguments](docs::attribute#tuple-style-arguments) or
165/// [raw arguments](docs::attribute#raw-arguments) depending upon the function
166/// signature.
167///
168/// ## Tuple-style arguments
169///
170/// Use a normal function signature. The parameters in the signature will be
171/// converted to a tuple. For example:
172///
173/// ```
174/// #[binrw::parser(reader: r, endian)]
175/// fn custom_parser(v0: u8, v1: i16) -> binrw::BinResult<()> {
176///     Ok(())
177/// }
178/// # custom_parser(&mut binrw::io::Cursor::new(b""), binrw::Endian::Little, (0, 0)).unwrap();
179/// ```
180///
181/// The transformed output for this function is:
182///
183/// ```
184/// use binrw::{BinResult, Endian, io::{Read, Seek}};
185/// fn custom_parser<R: Read + Seek>(
186///     r: &mut R,
187///     endian: Endian,
188///     (v0, v1): (u8, i16)
189/// ) -> BinResult<()> {
190///     Ok(())
191/// }
192/// # custom_parser(&mut binrw::io::Cursor::new(b""), binrw::Endian::Little, (0, 0)).unwrap();
193/// ```
194///
195/// ## Raw arguments
196///
197/// Use a *variadic* function signature with a single parameter. The name and
198/// type of the parameter will be used as the raw argument. For example:
199///
200/// ```
201/// # struct ArgsType;
202/// #[binrw::parser]
203/// fn custom_parser(args: ArgsType, ...) -> binrw::BinResult<()> {
204///     Ok(())
205/// }
206/// # custom_parser(&mut binrw::io::Cursor::new(b""), binrw::Endian::Little, ArgsType).unwrap();
207/// ```
208///
209/// The transformed output for this function is:
210///
211/// ```
212/// # struct ArgsType;
213/// use binrw::{BinResult, Endian, io::{Read, Seek}};
214/// fn custom_parser<R: Read + Seek>(
215///     _: &mut R,
216///     _: Endian,
217///     args: ArgsType
218/// ) -> BinResult<()> {
219///     Ok(())
220/// }
221/// # custom_parser(&mut binrw::io::Cursor::new(b""), binrw::Endian::Little, ArgsType).unwrap();
222/// ```
223///
224/// # Return value
225///
226/// The return value of a parser function must be [`BinResult<T>`](BinResult),
227/// where `T` is the type of the object being parsed.
228pub use binrw_derive::parser;
229
230/// Attribute macro used to generate
231/// [`write_with`](docs::attribute#custom-parserswriters) functions.
232///
233/// Rust functions are transformed by this macro to match the binrw API.
234///
235/// # Attribute options
236///
237/// * `#[writer(writer)]` or `#[writer(writer: $ident)]`: Exposes the write
238///   stream to the function. If no variable name is given, `writer` is used.
239/// * `#[writer(endian)]` or `#[writer(endian: $ident)]`: Exposes the endianness
240///   to the function. If no variable name is given, `endian` is used.
241///
242/// Options are comma-separated.
243///
244/// # Function parameters
245///
246/// The first parameter is required and receives a reference to the object being
247/// written.
248///
249/// Subsequent parameters are transformed into either
250/// [tuple-style arguments](docs::attribute#tuple-style-arguments) or
251/// [raw arguments](docs::attribute#raw-arguments) depending upon the function
252/// signature.
253///
254/// ## Tuple-style arguments
255///
256/// Use a normal function signature. The remaining parameters in the signature
257/// will be converted to a tuple. For example:
258///
259/// ```
260/// # struct Object;
261/// #[binrw::writer(writer: w, endian)]
262/// fn custom_writer(obj: &Object, v0: u8, v1: i16) -> binrw::BinResult<()> {
263///     Ok(())
264/// }
265/// # custom_writer(&Object, &mut binrw::io::Cursor::new(vec![]), binrw::Endian::Little, (0, 0)).unwrap();
266/// ```
267///
268/// The transformed output for this function is:
269///
270/// ```
271/// # struct Object;
272/// use binrw::{BinResult, Endian, io::{Seek, Write}};
273/// fn custom_writer<W: Write + Seek>(
274///     obj: &Object,
275///     w: &mut W,
276///     endian: Endian,
277///     (v0, v1): (u8, i16)
278/// ) -> BinResult<()> {
279///     Ok(())
280/// }
281/// # custom_writer(&Object, &mut binrw::io::Cursor::new(vec![]), binrw::Endian::Little, (0, 0)).unwrap();
282/// ```
283///
284/// ## Raw arguments
285///
286/// Use a *variadic* function signature with a second parameter. The name and
287/// type of the second parameter will be used as the raw argument. For example:
288///
289/// ```
290/// # struct Object;
291/// # struct ArgsType;
292/// #[binrw::writer]
293/// fn custom_writer(obj: &Object, args: ArgsType, ...) -> binrw::BinResult<()> {
294///     Ok(())
295/// }
296/// # custom_writer(&Object, &mut binrw::io::Cursor::new(vec![]), binrw::Endian::Little, ArgsType).unwrap();
297/// ```
298///
299/// The transformed output for this function is:
300///
301/// ```
302/// # struct Object;
303/// # struct ArgsType;
304/// use binrw::{BinResult, Endian, io::{Seek, Write}};
305/// fn custom_writer<W: Write + Seek>(
306///     obj: &Object,
307///     _: &mut W,
308///     _: Endian,
309///     args: ArgsType
310/// ) -> BinResult<()> {
311///     Ok(())
312/// }
313/// # custom_writer(&Object, &mut binrw::io::Cursor::new(vec![]), binrw::Endian::Little, ArgsType).unwrap();
314/// ```
315///
316/// # Return value
317///
318/// The return value of a writer function must be [`BinResult<()>`](BinResult).
319pub use binrw_derive::writer;
320
321/// A specialized [`Result`] type for binrw operations.
322pub type BinResult<T> = core::result::Result<T, Error>;
323
324pub mod prelude {
325    //! The binrw prelude.
326    //!
327    //! A collection of traits and types you’ll likely need when working with
328    //! binrw and are unlikely to cause name conflicts.
329    //!
330    //! ```
331    //! # #![allow(unused_imports)]
332    //! use binrw::prelude::*;
333    //! ```
334
335    pub use crate::{
336        binread, binrw, binwrite, BinRead, BinReaderExt, BinResult, BinWrite, BinWriterExt,
337    };
338}