const_str/
lib.rs

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