stack_cstr/
lib.rs

1#![allow(internal_features)]
2#![feature(slice_internals)]
3
4//! # stack_cstr
5//!
6//! `stack_cstr` provides ergonomic and efficient ways to create
7//! [`CStr`](std::ffi::CStr) values for FFI interoperability.
8//!
9//! The crate uses [`CArrayString`] to store C-compatible strings. It aims to
10//! minimize heap allocations for short strings by using a fixed-size stack buffer,
11//! while automatically falling back to heap allocation for longer strings.
12//!
13//! ## Motivation
14//!
15//! When interacting with C APIs, strings must be passed as null-terminated
16//! `*const c_char`. The standard approach in Rust is to use [`CString`], which
17//! always allocates on the heap.
18//!
19//! In performance-sensitive or embedded environments, frequent heap allocations
20//! are undesirable. `stack_cstr` allows you to create `CStr` objects backed
21//! by a stack buffer when possible, avoiding heap allocation for short-lived
22//! or small strings.
23//!
24//! ## Core Components
25//!
26//! - [`CArrayString`](crate::CArrayString): A string type that can be either
27//!   stack- or heap-backed, exposing both `*const c_char` and `&CStr`.
28//! - [`cstr!`](crate::cstr): A macro that constructs a `CArrayString` with
29//!   default stack allocation and falls back to heap if the string is too large.
30//!
31//! ## Example: Using the `cstr!` Macro
32//!
33//! ```
34//! use std::ffi::CStr;
35//! 
36//! use stack_cstr::cstr;
37//!
38//! let s = cstr!("Pi = {:.2}", 3.14159);
39//! assert_eq!(s.as_c_str().to_str().unwrap(), "Pi = 3.14");
40//!
41//! unsafe {
42//!     // Pass to FFI as *const c_char
43//!     let ptr = s.as_ptr();
44//!     assert_eq!(CStr::from_ptr(ptr).to_str().unwrap(), "Pi = 3.14");
45//! }
46//! ```
47//!
48//! ## Design Notes
49//!
50//! - `CArrayString` uses a stack buffer for small strings and falls back to heap
51//!   allocation for longer strings.
52//! - The `cstr!` macro simplifies usage by automatically creating a `CArrayString<128>`
53//!   with default stack size 128 bytes.
54//! - The returned type is `CArrayString<128>`. The internal storage may be stack- or
55//!   heap-based depending on the string length.
56//!
57//! ## Performance Considerations
58//!
59//! - Short strings that fit in the stack buffer avoid heap allocation.
60//! - Long strings are automatically allocated on the heap.
61//! - Choosing an appropriate buffer size (currently 128 bytes) can minimize heap fallback.
62//!
63//! ## Use Cases
64//!
65//! - Passing short strings to FFI calls without heap allocation.
66//! - Performance-sensitive applications where allocation patterns matter.
67//! - Embedded systems with constrained heap memory.
68//!
69//! ## Limitations
70//!
71//! - The default stack buffer size is fixed at 128 bytes in `cstr!`.
72//! - Strings longer than 128 bytes will always be heap-allocated.
73//!
74//! ## See Also
75//!
76//! - [`CString`](std::ffi::CString) for explicit heap-allocated C strings
77//! - [`CStr`](std::ffi::CStr) for borrowed C strings
78
79pub mod c_array_string;
80pub mod error;
81pub mod macros;
82
83pub use c_array_string::CArrayString;
84pub use error::{CStrError, ContainsNulError};