[](https://github.com/Fabus1184/bunpack/actions/workflows/rust.yml)
[](https://crates.io/crates/bunpack)
# bunpack
A library for packing and unpacking binary data in Rust using format strings similar to Python's `struct` module.
## Usage
```rust
use bunpack::{pack, unpack};
let data: Vec<u8> = pack!("i", 1234);
let value: i32 = unpack!("i", &data);
assert_eq!(value, 1234);
```
There is also a `std::io::Read` and `std::io::Write` variant for packing and unpacking directly from streams.
```rust
use std::io::Cursor;
let mut cursor = Cursor::new(Vec::new());
bunpack::pack_write!(&mut cursor, "<i?", 42, true).unwrap();
assert_eq!(cursor.get_ref().as_slice(), &[42, 0, 0, 0, 1]);
cursor.set_position(0);
let value: (i32, bool) = bunpack::unpack_read!(&mut cursor, "<i?").unwrap();
assert_eq!(value, (42, true));
```
# Format Specifiers
## Byte Order
Format specifiers can begin with an optional character to specify the byte order:
| `@` | Native byte order |
| `<` | Little-endian |
| `>` | Big-endian |
## Type Specifiers
Following the optional byte order, format specifiers can include one or more type specifiers:
| `c` | `char` | 4 |
| `b` | `i8` | 1 |
| `B` | `u8` | 1 |
| `?` | `bool` | 1 |
| `h` | `i16` | 2 |
| `H` | `u16` | 2 |
| `i` | `i32` | 4 |
| `I` | `u32` | 4 |
| `q` | `i64` | 8 |
| `Q` | `u64` | 8 |
| `o` | `i128` | 16 |
| `O` | `u128` | 16 |
| `n` | `isize` | native |
| `N` | `usize` | native |
| `f` | `f32` | 4 |
| `d` | `f64` | 8 |
| `s` | `&str` | pack: length of string |
| `p` | `&[u8]` | pack: length of byte array |
| `P` | `*const ()` | native |
## Repeat Counts
Type specifiers can be chained together to create tuples of values. For example, `iHf` specifies a `(i32, u16, f32)` tuple.
Type specifiers can be wrapped in Rust-style arrays to indicate repeat counts.
Example: `[i; 3]` specifies a `[i32; 3]` array, and `[i; 2][H; 4]` specifies `([i32; 2], [u16; 4])`.
```rust
let values = [(1, 1.0, '🐈'), (2, 2.0, '🐕'), (3, 3.0, '🦅')];
let bytes = bunpack::pack!("<[ifc; 3]", values);
let unpacked: [(i32, f32, char); 3] = bunpack::unpack!("<[ifc; 3]", &bytes);
assert_eq!(unpacked, values);
```
## More examples
```rust
let str = "Hello, World!";
let bytes = bunpack::pack!("<p", str.as_bytes());
let unpacked: [u8; 13] = bunpack::unpack!("[B;13]", &bytes);
assert_eq!(unpacked, *str.as_bytes());
```
---
```rust
let str = "Hello, World!";
let bytes = bunpack::pack!("<p", str.as_bytes());
let unpacked: [u8; 13] = bunpack::unpack!("[B;13]", &bytes);
assert_eq!(unpacked, *str.as_bytes());
```
---
```rust
let bytes = bunpack::pack!(">H", 0x1234);
let unpacked: u16 = bunpack::unpack!("<H", &bytes);
assert_eq!(unpacked, 0x3412);
```