cheetah_string/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]
2#![deny(unsafe_op_in_unsafe_fn)]
3
4//! An immutable, clone-cheap UTF-8 value for latency-sensitive systems.
5//!
6//! [`CheetahString`] has one constructor-independent value contract:
7//!
8//! - values up to 23 bytes are stored inline;
9//! - static values borrow their `&'static str`;
10//! - other long values use a shared `Arc<str>` backing.
11//!
12//! Long clones are bounded O(1) and allocate zero times. Append-heavy
13//! construction belongs to [`CheetahBuilder`]; call
14//! [`CheetahBuilder::finish`] to freeze the value or
15//! [`CheetahBuilder::into_string`] when mutation or spare capacity must
16//! continue. `from_string` freezes its input and does not retain a mutable
17//! `String` representation.
18//!
19//! The crate supports `no_std + alloc`. Optional `serde` integration preserves
20//! the text contract, while the `bytes` feature exposes [`CheetahBytes`] for
21//! byte-oriented data. Byte-to-text conversion validates and copies; only
22//! `bytes::Bytes <-> CheetahBytes` is zero-copy.
23//!
24//! # Split capability
25//!
26//! [`CheetahString::split_char`] returns a double-ended standard iterator.
27//! [`CheetahString::split_str`] is forward-only, so unsupported reverse
28//! iteration fails at compile time rather than panicking at runtime.
29//!
30//! # Search and experimental SIMD
31//!
32//! Stable builds delegate equality, prefix, and suffix comparisons to the
33//! standard slice/`str` implementations so the compiler and standard library
34//! select the best portable strategy. The `experimental-simd` feature exposes
35//! an x86_64 SSE2 experiment for controlled benchmarking only. The deprecated
36//! `simd` feature remains an alpha compatibility alias.
37//!
38//! Substring search through `find()` and `contains()` continues to use
39//! `memchr`/`memmem`, which is the stable default search backend.
40//!
41//! To opt into the isolated experiment:
42//!
43//! ```toml
44//! [dependencies]
45//! cheetah-string = { version = "=3.0.0-alpha.1", features = ["experimental-simd"] }
46//! ```
47//!
48//! # Example
49//!
50//! ```rust
51//! use cheetah_string::{CheetahBuilder, CheetahString};
52//!
53//! let topic = CheetahString::from_static_str("orders");
54//! assert!(topic.starts_with("ord"));
55//!
56//! let mut builder = CheetahBuilder::with_capacity(32);
57//! builder.push_str(topic.as_str());
58//! builder.push('@');
59//! builder.push_str("group-a");
60//!
61//! let route = builder.finish();
62//! assert_eq!(route, "orders@group-a");
63//! ```
64extern crate alloc;
65
66mod builder;
67mod cheetah_string;
68mod error;
69mod inline;
70mod search;
71
72#[cfg(feature = "bytes")]
73#[path = "bytes.rs"]
74mod cheetah_bytes;
75
76#[cfg(feature = "serde")]
77mod serde;
78
79#[cfg(all(feature = "experimental-simd", target_arch = "x86_64"))]
80mod simd;
81
82#[cfg(feature = "experimental-packed")]
83pub mod packed;
84
85#[cfg(feature = "bytes")]
86pub use cheetah_bytes::{CheetahBytes, FromUtf8BytesError};
87
88pub use builder::CheetahBuilder;
89pub use cheetah_string::{CheetahString, SplitPattern, SplitStr, StrPattern};
90pub use error::{Error, Result};
91pub use search::CheetahFinder;
92
93/// Deprecated v3 compatibility name for [`CheetahString`].
94///
95/// `CheetahString` is now itself immutable and clone-cheap, so a second value
96/// type no longer carries a distinct contract.
97#[deprecated(since = "3.0.0", note = "use CheetahString")]
98pub type CheetahStr = CheetahString;