| Crates.io | copy-stack-vec |
| lib.rs | copy-stack-vec |
| version | 0.1.0 |
| created_at | 2025-11-14 02:20:57.308354+00 |
| updated_at | 2025-11-18 22:25:22.56491+00 |
| description | A no_std, fixed-capacity, stack-allocated Copy vector for Copy types, with no unsafe code by default. |
| homepage | https://github.com/nemynm/copy-stack-vec |
| repository | https://github.com/nemynm/copy-stack-vec |
| max_upload_size | |
| id | 1932154 |
| size | 140,026 |
A no_std, fixed-capacity, stack-allocated vector type for Copy elements, with no unsafe code by default.
CopyStackVec<T, N> stores up to N elements inline and provides familiar slice/Vec-like ergonomics without heap
allocation or runtime growth. In the default backend, many constructors require T: Copy + Default,
while some helpers (like new_with and From<[T; N]>) only need T: Copy. With the
unsafe-maybe-uninit backend, only T: Copy is required.
no_std compatible.unsafe in the default backend (#![forbid(unsafe_code)]).N known at compile time).Copy (value semantics; moving copies the whole buffer).unsafe-maybe-uninit backend.serde support.Add the crate to your project
cargo add copy-stack-vec
use copy_stack_vec::CopyStackVec;
let mut v: CopyStackVec<u8, 4> = CopyStackVec::default();
v.extend_from_slice(&[1, 2, 3]).unwrap();
assert_eq!(v.as_slice(), &[1, 2, 3]);
let mut w: CopyStackVec<u8, 4> = CopyStackVec::default();
w.push(1).unwrap();
w.extend_from_slice(&[2, 3]).unwrap();
assert_eq!(w.as_slice(), &[1, 2, 3]);
The copy-stack-vec crate can be a good fit when:
you need a small fixed-capacity buffer on the stack;
you prefer value semantics (the container itself is Copy) and your element type is Copy;
you want a crate that defaults to no unsafe code;
you want deterministic, heap-allocation-free behavior.
It may not be the best tool if:
Well-established alternatives exist already (arrayvec, heapless, smallvec, or tinyvec to name a few).
copy-stack-vec is a focused option built around value semantics (the container itself is Copy) and
safe-by-default internals for Copy element types.
[T; N].T: Copy + Default for most constructors that build a fresh buffer [1]#![forbid(unsafe_code)]).O(N) when constructing a new vector (eager initialization).[1] some helpers like CopyStackVec::new_with and From<[T; N]> only require T: Copy. See method documentation.
unsafe-maybe-uninit backend (optional)storage is [MaybeUninit<T>; N]
only requires T: Copy
avoids eager initialization of all N elements
uses minimal, well-scoped internal unsafe
CopyStackVec follows Rust slice and Vec semantics for indexing and range-based operations:
v[i], v[start..end], etc.) panics on out-of-bounds
or inverted ranges - just like slices.drain(range) behaves the same as Vec::drain(range):
start > end or end > len()-> panicstart == end -> empty iterator, no changesCapacity errors never panic; only range / indexing violations do.
The API explicitly distinguishes two behaviors for capacity-sensitive operations.
pushextend_from_sliceresizetry_frominserttry_from_itertry_removetry_swap_removeThese take up to capacity and do not consume further items once the vector is full:
push_truncatedextend_from_slice_truncatedfrom_slice_truncatedfrom_array_truncatedExtend<T>FromIterator<T>Note: unlike Vec, collecting into CopyStackVec (via FromIterator / collect::<CopyStackVec<_, N>>())
takes at most the first N elements from the iterator and stops there, leaving the remaining items unconsumed.
serde - enable Serialize / Deserializeunsafe-maybe-uninit - switch to the MaybeUninit backend and relax T: Default requirementsThis crate is tested on and supports Rust 1.85 and newer.
MSRV policy:
0.3.x -> 0.4.0).MIT OR Apache-2.0