Expand description
This crate provides macros to efficiently concatenate strings without extra side-effects.
Basic usage:
use str_cat::str_cat;
let s = str_cat!("Hello", " ", "World", "!");
assert_eq!(s, "Hello World!");Which is roughly equivalent to
let mut s = String::with_capacity("Hello".len() + " ".len() + "World".len() + "!".len());
s.push_str("Hello");
s.push_str(" ");
s.push_str("World");
s.push_str("!");The macro runs without extra side-effects, which means all involved expressions are evaluated only once.
let mut get_world_calls = 0;
let mut get_world = || {
get_world_calls += 1;
"World"
};
let s = str_cat!("Hello", " ", get_world(), "!");
assert_eq!(s, "Hello World!");
assert_eq!(get_world_calls, 1);Custom minimum capacity.
let s = str_cat!(String::with_capacity(16); "foo", "bar");
assert_eq!(s, "foobar");
assert_eq!(s.capacity(), 16);Reuse existing allocation.
let mut s = "Hello World!".to_owned();
let ptr = s.as_ptr();
let cap = s.capacity();
s.clear();
str_cat!(&mut s; "World!");
assert_eq!(s, "World!");
// Did not grow
assert_eq!(s.as_ptr(), ptr);
assert_eq!(s.capacity(), cap);Works with any expressions that can dereference to str when
evaluated. Although it would be more simple and efficient to use
format! instead when you can’t avoid explicit .to_string()
calls.
// Just an example. It's better to use `format!` in this case.
let s = str_cat!(
"Hello".to_owned(),
Box::new(" "),
['W', 'o', 'r', 'l', 'd'].iter().collect::<String>(),
'!'.to_string(),
123456.to_string(),
);
assert_eq!(s, "Hello World!123456");There are also variants for PathBuf,
OsString and Vec.
use str_cat::os_str_cat;
// Works for anything that implements AsRef<OsStr>.
let s = os_str_cat!(
OsStr::new("Hello"),
OsStr::new(" ").to_owned(),
Path::new("World"),
"!",
);
assert_eq!(s, OsStr::new("Hello World!"));