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}