1 /// Encode a string literal as a [`&CStr8`].
2 ///
3 /// The encoding is done at compile time, so the result can be used in a
4 /// `const` item.
5 ///
6 /// An empty string containing just a null character can be created with either
7 /// `cstr8!()` or `cstr8!("")`.
8 ///
9 /// # Example
10 ///
11 /// ```
12 /// use uefi::{CStr8, cstr8};
13 ///
14 /// const S: &CStr8 = cstr8!("abÿ");
15 /// assert_eq!(S.as_bytes(), [97, 98, 255, 0]);
16 ///
17 /// const EMPTY: &CStr8 = cstr8!();
18 /// assert_eq!(EMPTY.as_bytes(), [0]);
19 /// assert_eq!(cstr8!(""), EMPTY);
20 /// ```
21 ///
22 /// [`&CStr8`]: crate::CStr8
23 #[macro_export]
24 macro_rules! cstr8 {
25     () => {{
26         const S: &[u8] = &[0];
27         // SAFETY: `S` is a trivially correct Latin-1 C string.
28         unsafe { $crate::CStr8::from_bytes_with_nul_unchecked(S) }
29     }};
30     ($s:literal) => {{
31         // Use `const` values here to force errors to happen at compile
32         // time.
33 
34         // Add one for the null char.
35         const NUM_CHARS: usize = $crate::data_types::str_num_latin1_chars($s) + 1;
36 
37         const VAL: [u8; NUM_CHARS] = $crate::data_types::str_to_latin1($s);
38 
39         // SAFETY: the `str_to_latin1` function always produces a valid Latin-1
40         // string with a trailing null character.
41         unsafe { $crate::CStr8::from_bytes_with_nul_unchecked(&VAL) }
42     }};
43 }
44 
45 /// Encode a string literal as a [`&CStr16`].
46 ///
47 /// The encoding is done at compile time, so the result can be used in a
48 /// `const` item.
49 ///
50 /// An empty string containing just a null character can be created with either
51 /// `cstr16!()` or `cstr16!("")`.
52 ///
53 /// # Example
54 ///
55 /// ```
56 /// use uefi::{CStr16, cstr16};
57 ///
58 /// const S: &CStr16 = cstr16!("abc");
59 /// assert_eq!(S.to_u16_slice_with_nul(), [97, 98, 99, 0]);
60 ///
61 /// const EMPTY: &CStr16 = cstr16!();
62 /// assert_eq!(EMPTY.to_u16_slice_with_nul(), [0]);
63 /// assert_eq!(cstr16!(""), EMPTY);
64 /// ```
65 ///
66 /// [`&CStr16`]: crate::CStr16
67 #[macro_export]
68 macro_rules! cstr16 {
69     () => {{
70         const S: &[u16] = &[0];
71         // SAFETY: `S` is a trivially correct UCS-2 C string.
72         unsafe { $crate::CStr16::from_u16_with_nul_unchecked(S) }
73     }};
74     ($s:literal) => {{
75         const S: &[u16] = &$crate::ucs2_cstr!($s);
76         // SAFETY: the ucs2_cstr macro always produces a valid UCS-2 string with
77         // a trailing null character.
78         unsafe { $crate::CStr16::from_u16_with_nul_unchecked(S) }
79     }};
80 }
81