1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! # pack-io
//!
//! Compact binary wire format for Rust. Combines speed, schema evolution, and
//! zero-copy deserialization under a single coherent contract.
//!
//! ## At a glance (v0.3.0)
//!
//! - **Tier 1** — [`encode`] and [`decode`]: one line each direction.
//! - **Tier 2** —
//! - [`Encoder`] / [`Decoder`] for in-memory buffers.
//! - [`IoEncoder`] / [`IoDecoder`] for `std::io::Write` / `Read` streams
//! (`std`-gated).
//! - [`encode_into`] / [`decode_from`] convenience helpers over Read/Write.
//! - **Tier 3** — implement [`Serialize`] / [`Deserialize`] on your own
//! types. Both traits are generic over the [`Encode`] / [`Decode`]
//! behaviour traits, so one impl works through every encoder / decoder
//! the crate ships.
//!
//! ## Primitive support
//!
//! Integers (`u8` … `u128`, `i8` … `i128`, `usize` / `isize`), `bool`,
//! `f32`, `f64`, `String` / `&str`, fixed-size arrays `[T; N]`, tuples of
//! arity 1…12, `Option<T>`, `Result<T, E>`, and `()`.
//!
//! ## Collection support (new in v0.3)
//!
//! `Vec<T>` / `&[T]`, `BTreeMap<K, V>`, `BTreeSet<T>`, and (with the default
//! `std` feature) `HashMap<K, V>` and `HashSet<T>`. **Hash-based collections
//! encode in canonical key-sorted order** so that hashing, signing, or
//! content-addressing the output is safe regardless of insertion order or
//! hash randomisation.
//!
//! ## Wire-format freeze
//!
//! Starting at `v0.3.0` the wire format is **frozen** for the `1.x` line.
//! See [`docs/WIRE_FORMAT.md`](https://github.com/jamesgober/pack-io/blob/main/docs/WIRE_FORMAT.md)
//! for the normative byte-level spec.
//!
//! ## Quick start
//!
//! ```
//! use pack_io::{encode, decode};
//!
//! let bytes = encode(&(7_u64, true, String::from("hello"))).unwrap();
//! let back: (u64, bool, String) = decode(&bytes).unwrap();
//! assert_eq!(back, (7, true, String::from("hello")));
//! ```
//!
//! ## Invariants
//!
//! - **Round-trip integrity** — `decode(encode(v)) == v` for every supported
//! type, under any input.
//! - **Determinism** — the same value always produces the same bytes,
//! regardless of insertion order, platform, or build flags.
//! - **Safe decode** — no panic, no unbounded allocation, no read past the
//! input, on any byte sequence.
//! - **Wire-format stability** — frozen at `0.3.0`; any `1.x` decoder reads
//! any `1.x`-or-earlier encoding.
//!
//! ## `no_std`
//!
//! `pack-io` is `no_std`-capable. The default build enables `std` for the
//! [`std::error::Error`] impl, `HashMap` / `HashSet` integration, and the
//! [`io`] module. Disable the default feature to compile against `core` +
//! `alloc` only:
//!
//! ```toml
//! pack-io = { version = "0.3", default-features = false }
//! ```
extern crate alloc;
extern crate std;
pub use crate;
pub use crate;
pub use crate;
pub use crate;
pub use crate;
// Re-export the derive macros when the `derive` feature is on. Users write
// `#[derive(pack_io::Serialize, pack_io::Deserialize, pack_io::DeserializeView)]`
// and the proc-macro crate is the implementation detail.
pub use ;
/// Semantic version of this crate, as declared in `Cargo.toml`.
///
/// # Examples
///
/// ```
/// assert!(pack_io::VERSION.starts_with("0."));
/// ```
pub const VERSION: &str = env!;