1 // Copyright 2023, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Provide a safe const-compatible no_std macro for readable &'static CStr.
16 
17 #![no_std]
18 
19 /// Create &CStr out of &str literal
20 #[macro_export]
21 macro_rules! cstr {
22     ($str:literal) => {{
23         const S: &str = concat!($str, "\0");
24         const C: &::core::ffi::CStr = match ::core::ffi::CStr::from_bytes_with_nul(S.as_bytes()) {
25             Ok(v) => v,
26             Err(_) => panic!("string contains interior NUL"),
27         };
28         C
29     }};
30 }
31 
32 #[cfg(test)]
33 mod tests {
34     use super::*;
35     use std::ffi::CString;
36 
37     #[test]
valid_input_string()38     fn valid_input_string() {
39         let expected = CString::new("aaa").unwrap();
40         assert_eq!(cstr!("aaa"), expected.as_c_str());
41     }
42 
43     #[test]
valid_empty_string()44     fn valid_empty_string() {
45         let expected = CString::new("").unwrap();
46         assert_eq!(cstr!(""), expected.as_c_str());
47     }
48 
49     // As cstr!() panics at compile time, tests covering invalid inputs fail to compile!
50 }
51