fast_concat/
lib.rs

1#![no_std]
2#![doc = include_str!("../README.md")]
3#![deny(clippy::unwrap_used)]
4#![deny(clippy::expect_used)]
5#![warn(clippy::pedantic)]
6#![warn(clippy::nursery)]
7#![deny(clippy::unwrap_used, clippy::expect_used)]
8#![allow(clippy::must_use_candidate)]
9#![warn(missing_debug_implementations)]
10#![warn(missing_copy_implementations)]
11#![allow(clippy::module_name_repetitions)]
12#![warn(
13    clippy::arithmetic_side_effects,
14    clippy::unreachable,
15    clippy::unchecked_duration_subtraction,
16    clippy::todo,
17    clippy::string_slice,
18    clippy::panic_in_result_fn,
19    clippy::indexing_slicing,
20    clippy::panic,
21    clippy::exit,
22    clippy::as_conversions,
23    clippy::large_futures,
24    clippy::large_stack_arrays,
25    clippy::large_stack_frames,
26    clippy::modulo_one,
27    clippy::mem_replace_with_uninit,
28    clippy::iterator_step_by_zero,
29    clippy::invalid_regex,
30    clippy::print_stdout,
31    clippy::print_stderr
32)]
33
34/// Concatenates string expressions.
35///
36/// If you only pass in literals or constants, you will get a const `&'static str` back.
37/// Otherwise, this macro will create a buffer with the optimal capacity and push every string to it.
38///
39/// # Syntax
40///
41/// Any amount of expressions that evaluate to a `&str` separated by commas.
42/// An expression can be prefixed with `const` to indicate that it is constant.
43///
44/// # Examples
45///
46/// ```rust
47/// # use fast_concat_macro::fast_concat;
48/// const CONST: &str = "const ";
49/// let var = "var ";
50/// let mut buf = String::new();
51///
52/// // use const keyword to indicate that it is constant
53/// let expansion = fast_concat!("lit0 ", const CONST, var, "lit1 ", "lit2 ", 9, {
54///     for i in 0..10 {
55///         buf.push_str(&i.to_string());
56///     }
57///
58///     &buf
59/// });
60///
61/// buf.clear();
62///
63/// // what the value is
64/// assert_eq!(expansion, "lit0 const var lit1 lit2 90123456789");
65///
66/// // what code gets generated
67/// assert_eq!(expansion, {
68///     extern crate alloc;
69///     // constcat generates these
70///     const _0: &'static str = "lit0 const ";
71///     let _1: &str = var;
72///     const _2: &'static str = "lit1 lit2 9";
73///     let _3: &str = {
74///         for i in 0..10 {
75///             buf.push_str(&i.to_string());
76///         }
77///
78///         &buf
79///     };
80///
81///     let mut buf = alloc::string::String::with_capacity(0 + _0.len() + _1.len() + _2.len() + _3.len());
82///     buf.push_str(_0);
83///     buf.push_str(_1);
84///     buf.push_str(_2);
85///     buf.push_str(_3);
86///     buf
87/// });
88/// ```
89///
90/// ```rust
91/// # use fast_concat_macro::fast_concat;
92///
93/// const ASSETS_DIR: &str = "./assets";
94/// const ICON: &str = fast_concat!(const ASSETS_DIR, '/', "icon.png");
95///
96/// assert_eq!(ICON, "./assets/icon.png");
97/// assert_eq!(ICON, {
98///     const OUTPUT: &'static str = ::constcat::concat!(ASSETS_DIR, '/', "icon.png" , );
99///     OUTPUT
100/// });
101/// ```
102pub use fast_concat_macro::fast_concat;
103
104#[cfg(test)]
105mod tests {
106    extern crate alloc;
107    use alloc::string::{String, ToString};
108    use fast_concat_macro::fast_concat;
109
110    #[test]
111    fn concat() {
112        const CONST: &str = "const ";
113        let var = "var ";
114        let mut buf = String::new();
115
116        macro_rules! impure_expr {
117            ($buf:ident) => {{
118                for i in 0..10 {
119                    $buf.push_str(&i.to_string());
120                }
121                &$buf
122            }};
123        }
124
125        let correct_output = "lit0 const var lit1 lit2 90123456789";
126
127        assert_eq!(
128            fast_concat!("lit0 ", const CONST, var, "lit1 ", "lit2 ", 9, impure_expr!(buf)),
129            correct_output
130        );
131
132        let correct_output = "lit0 const var lit1 lit2 901234567890123456789";
133
134        assert_eq!(
135            fast_concat!("lit0 ", const CONST, var, "lit1 ", "lit2 ", 9, impure_expr!(buf)),
136            correct_output
137        );
138    }
139}