macro_rules! c_str {
($str:expr) => {{
const STRING: &str = concat!($str, "\0");
const BYTES: &[u8] = STRING.as_bytes();
const fn f(b: &[u8], i: usize) {
if i == b.len() - 1 {
} else if b[i] == 0 {
panic!("c_str argument contains NUL")
} else {
f(b, i + 1)
}
}
f(BYTES, 0);
unsafe { std::ffi::CStr::from_bytes_with_nul_unchecked(BYTES) }
}};
}
pub(crate) use c_str;
#[cfg(test)]
mod tests {
use std::ffi::CStr;
#[test]
fn test_cstr_macro() {
let good = c_str!("🦀");
let good_bytes = b"\xf0\x9f\xa6\x80\0";
assert_eq!(good.to_bytes_with_nul(), good_bytes);
}
#[test]
fn test_cstr_macro_const() {
const GOOD: &CStr = c_str!("🦀");
const GOOD_BYTES: &[u8] = b"\xf0\x9f\xa6\x80\0";
assert_eq!(GOOD.to_bytes_with_nul(), GOOD_BYTES);
}
}