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
// Copyright (c) 2025-2026 Federico Hoerth <memparanoid@gmail.com>
// SPDX-License-Identifier: GPL-3.0-only
// See LICENSE in the repository root for full license text.
//! Secure allocation containers with automatic zeroization.
//!
//! This crate provides four main types:
//!
//! - [`AllockedVec`]: Capacity-locked Vec with fallible operations
//! - [`RedoubtArray`]: Fixed-size array with automatic zeroization
//! - [`RedoubtVec`]: Auto-growing Vec with safe reallocation (2x growth)
//! - [`RedoubtString`]: Auto-growing String with safe reallocation (2x growth)
//!
//! # Core Guarantees
//!
//! - **Controlled capacity**: Once sealed with `reserve_exact()`, that method cannot be called
//! again. To change capacity, use `realloc_with_capacity()` which safely zeroizes the old
//! allocation before creating a new one.
//! - **Automatic zeroization**: All data is zeroized on drop via `#[fast_zeroize(drop)]`
//! - **Fallible operations**: `push()` and `reserve_exact()` fail instead of reallocating,
//! preventing unintended copies of data
//!
//! # Example: Basic Usage
//!
//! ```rust
//! use redoubt_alloc::{AllockedVec, AllockedVecError};
//!
//! fn example() -> Result<(), AllockedVecError> {
//! let mut vec = AllockedVec::<u8>::new();
//! vec.reserve_exact(10)?;
//!
//! // Now sealed - cannot reserve again
//! assert!(vec.reserve_exact(20).is_err());
//!
//! // Push works while capacity allows
//! for i in 0u8..10 {
//! vec.push(i)?;
//! }
//!
//! // Exceeding capacity fails
//! assert!(vec.push(42).is_err());
//! Ok(())
//! }
//! # example().unwrap();
//! ```
//!
//! # Example: Controlled Reallocation
//!
//! ```rust
//! use redoubt_alloc::{AllockedVec, AllockedVecError};
//!
//! fn example() -> Result<(), AllockedVecError> {
//! let mut vec = AllockedVec::<u8>::with_capacity(5);
//! vec.push(1)?;
//! vec.push(2)?;
//!
//! // Change capacity with realloc_with_capacity()
//! // This zeroizes the old allocation before creating the new one
//! vec.realloc_with_capacity(10);
//!
//! for i in 3u8..=10 {
//! vec.push(i)?;
//! }
//!
//! assert_eq!(vec.len(), 10);
//! assert_eq!(vec.capacity(), 10);
//! Ok(())
//! }
//! # example().unwrap();
//! ```
//!
//! # Test Utilities
//!
//! Enable the `test-utils` feature to inject failures for testing error handling paths:
//!
//! ```toml
//! [dev-dependencies]
//! redoubt-alloc = { version = "*", features = ["test-utils"] }
//! ```
//!
//! Then use [`AllockedVecBehaviour`] to test error scenarios:
//!
//! ```rust
//! // test-utils feature required in dev-dependencies
//! #[cfg(test)]
//! mod tests {
//! use redoubt_alloc::{AllockedVec, AllockedVecBehaviour};
//!
//! #[test]
//! fn test_handles_push_failure() {
//! let mut vec = AllockedVec::with_capacity(10);
//! vec.change_behaviour(AllockedVecBehaviour::FailAtPush);
//!
//! // Test that your code handles the error correctly
//! assert!(vec.push(1u8).is_err());
//! }
//! }
//! ```
//!
//! ## License
//!
//! GPL-3.0-only
extern crate alloc;
pub use AllockedVec;
pub use ;
pub use RedoubtArray;
pub use RedoubtOption;
pub use RedoubtString;
pub use RedoubtVec;
pub use AllockedVecBehaviour;