With the recent improvements to const fn
it is possible to concat &str into &[u8]. It still needs a macro but not a procedural macro. However, I'm not sure how to get a &str
output at compile time. I think you need to do that conversion at runtime:
Playground
macro_rules! combine {
($A:expr, $B:expr) => {{
const LEN: usize = $A.len() + $B.len();
const fn combine(a: &'static str, b: &'static str) -> [u8; LEN] {
let mut out = [0u8; LEN];
out = copy_slice(a.as_bytes(), out, 0);
out = copy_slice(b.as_bytes(), out, a.len());
out
}
const fn copy_slice(input: &[u8], mut output: [u8; LEN], offset: usize) -> [u8; LEN] {
let mut index = 0;
loop {
output[offset+index] = input[index];
index += 1;
if index == input.len() { break }
}
output
}
combine($A, $B)
}}
}
const BASE: &'static str = "path/to";
const PART: &'static str = "foo";
const PATH: &'static [u8] = &combine!(BASE, PART);
fn main() {
// Once you're confident it's working you can use `from_utf8_unchecked` here.
let s = std::str::from_utf8(PATH).expect("Something went badly wrong at compile time.");
dbg!(s);
}
Hopefully const generics and continued const fn
improvements will make this situation better in the future.