const_str/
lib.rs

1//! Compile-time string operations.
2//! See the [macro list](#macros) for what you need.
3//!
4//! ## MSRV history
5//!
6//! Current: Rust 1.77.0
7//!
8//! - `v0.6.0`: Rust 1.77.0
9//! - `v0.5.7`: Rust 1.65.0
10//! - `v0.5.0`: Rust 1.64.0
11//! - `v0.4.0`: Rust 1.61.0
12//!
13//! ## Troubleshoot
14//!
15//! You don't have to care about this section
16//! unless you come across some compile errors about const evaluation.
17//!
18//! ```txt
19//! error[E0435]: attempt to use a non-constant value in a constant
20//! ```
21//!
22//! There are mainly two kinds of macros in this crate,
23//! which have different requirements for the arguments.
24//! - [const-context only](#const-context-only)
25//! - [const-fn compatible](#const-fn-compatible)
26//!
27//! ### const-context only
28//!
29//! These macros can only be used in [const contexts][const-context].
30//! The expanded code is equivalent to compute new [constant items][const-item].
31//! It implies that the *arguments* of these macros must be constant values,
32//! similar to [`consteval`][consteval] in C++ world.
33//!
34//! The following examples will not work:
35//! ```compile_fail
36//! const fn foo(a: &str, b: &str) -> &str {
37//!    const_str::concat!(a, b)
38//! }
39//! ```
40//! ```compile_fail
41//! const C: &str = {
42//!     let a = "Hello";
43//!     let b = "World";
44//!     const_str::concat!(a, b);
45//! };
46//! ```
47//!
48//! Instead, this way will work:
49//! ```
50//! const A: &str = "Hello";
51//! const B: &str = "World";
52//! const C: &str = const_str::concat!(A, " ", B);
53//! assert_eq!(C, "Hello World");
54//! ```
55//!
56//! ### const-fn compatible
57//!
58//! These macros can be used in [const contexts][const-context] and [const functions][const-fn].
59//! The expanded code is equivalent to calling const functions.
60//! It implies that the *arguments* of these macros can be any expressions,
61//! similar to [`constexpr`][constexpr] in C++ world.
62//!
63//! ```
64//! const fn calc(y: &str, m: &str, d: &str) -> u64 {
65//!     let y = const_str::parse!(y, u64);
66//!     let m = const_str::parse!(m, u64);
67//!     let d = const_str::parse!(d, u64);
68//!     (y * 10000 + m * 100 + d)
69//! }
70//! const TIME: u64 = calc("2025", "01", "26");
71//! assert_eq!(TIME, 20250126);
72//! ```
73//!
74//! You can also use these macros in normal functions,
75//! but they may be much slower than the runtime equivalents.
76//! It's recommended to use them only if you need compile-time evaluation.
77//!
78//! [const-context]: https://doc.rust-lang.org/reference/const_eval.html#const-context
79//! [const-fn]: https://doc.rust-lang.org/reference/const_eval.html#const-functions
80//! [const-item]: https://doc.rust-lang.org/reference/items/constant-items.html
81//! [consteval]: https://en.cppreference.com/w/cpp/language/consteval
82//! [constexpr]: https://en.cppreference.com/w/cpp/language/constexpr
83//!
84#![deny(unsafe_code, missing_docs, clippy::all, clippy::cargo)]
85#![allow(
86    clippy::missing_docs_in_private_items,
87    clippy::missing_inline_in_public_items,
88    clippy::implicit_return
89)]
90#![cfg_attr(not(any(test, feature = "std")), no_std)]
91#![cfg_attr(docsrs, feature(doc_cfg))]
92#![cfg_attr(feature = "unstable", allow(clippy::incompatible_msrv))]
93
94#[allow(unused_macros)]
95macro_rules! cfg_group {
96    ($($item:item)*) => {
97        $($item)*
98    }
99}
100
101mod ascii;
102mod bytes;
103mod printable;
104mod slice;
105mod str;
106mod utf16;
107mod utf8;
108
109#[doc(hidden)]
110#[cfg(feature = "proc")]
111pub mod __proc {
112    mod case;
113    pub use self::case::*;
114
115    mod fmt;
116    pub use self::fmt::*;
117
118    #[cfg(feature = "http")]
119    cfg_group! {
120        mod http;
121        pub use self::http::*;
122    }
123
124    #[cfg(feature = "regex")]
125    cfg_group! {
126        mod regex;
127        pub use self::regex::*;
128    }
129}
130
131#[doc(hidden)]
132pub mod __ctfe {
133    mod ascii_case;
134    pub use self::ascii_case::*;
135
136    mod chain;
137    // pub use self::chain::*;
138
139    mod compare;
140    pub use self::compare::*;
141
142    mod concat;
143    pub use self::concat::*;
144
145    mod concat_bytes;
146    pub use self::concat_bytes::*;
147
148    mod cstr;
149    pub use self::cstr::*;
150
151    mod encode;
152    pub use self::encode::*;
153
154    mod equal;
155    pub use self::equal::*;
156
157    mod find;
158    pub use self::find::*;
159
160    mod fmt;
161    pub use self::fmt::*;
162
163    mod hex;
164    pub use self::hex::*;
165
166    mod net;
167    pub use self::net::*;
168
169    mod parse;
170    pub use self::parse::*;
171
172    mod repeat;
173    pub use self::repeat::*;
174
175    mod replace;
176    pub use self::replace::*;
177
178    mod str;
179    pub use self::str::*;
180
181    mod to_byte_array;
182    pub use self::to_byte_array::*;
183
184    mod to_char_array;
185    pub use self::to_char_array::*;
186
187    mod to_str;
188    pub use self::to_str::*;
189
190    mod sorted;
191    pub use self::sorted::*;
192
193    mod split;
194    pub use self::split::*;
195
196    mod squish;
197    pub use self::squish::*;
198
199    mod is_ascii;
200    pub use self::is_ascii::*;
201
202    mod eq_ignore_ascii_case;
203    pub use self::eq_ignore_ascii_case::*;
204
205    mod unwrap;
206    pub use self::unwrap::*;
207
208    mod trim_ascii;
209    pub use self::trim_ascii::*;
210}