blob: ddf20fca18cbd00ce3ccdbc095d62244cd9fc3d5 [file] [log] [blame]
Pierre-Clément Tosi1bf532b2023-11-13 11:06:20 +00001// 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]
21macro_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)]
33mod tests {
34 use super::*;
35 use std::ffi::CString;
36
37 #[test]
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]
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}