Messages in this thread | | | Date | Mon, 14 Nov 2022 14:39:28 +0000 | From | Gary Guo <> | Subject | Re: [PATCH v1 19/28] rust: str: add `c_str!` macro |
| |
On Thu, 10 Nov 2022 17:41:31 +0100 Miguel Ojeda <ojeda@kernel.org> wrote:
> From: Gary Guo <gary@garyguo.net> > > Add `c_str!`, which is a convenience macro that creates a new `CStr` > from a string literal. > > It is designed to be similar to a `str` in usage, and it is usable > in const contexts, for instance: > > const X: &CStr = c_str!("Example"); > > Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com> > Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com> > Signed-off-by: Gary Guo <gary@garyguo.net> > [Reworded, adapted for upstream and applied latest changes] > Signed-off-by: Miguel Ojeda <ojeda@kernel.org> > --- > rust/kernel/str.rs | 32 ++++++++++++++++++++++++++++++++ > 1 file changed, 32 insertions(+) > > diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs > index 3ed685cb5a3c..3fb73b888dce 100644 > --- a/rust/kernel/str.rs > +++ b/rust/kernel/str.rs > @@ -128,6 +128,18 @@ impl CStr { > Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) }) > } > > + /// Creates a [`CStr`] from a `[u8]`, panic if input is not valid. > + /// > + /// This function is only meant to be used by `c_str!` macro, so > + /// crates using `c_str!` macro don't have to enable `const_panic` feature.
I wrote this code when `const_panic` was not yet stable. Now we have stable const panic this function could be removed.
> + #[doc(hidden)] > + pub const fn from_bytes_with_nul_unwrap(bytes: &[u8]) -> &Self { > + match Self::from_bytes_with_nul(bytes) { > + Ok(v) => v, > + Err(_) => panic!("string contains interior NUL"), > + } > + } > + > /// Creates a [`CStr`] from a `[u8]` without performing any additional > /// checks. > /// > @@ -321,6 +333,26 @@ where > } > } > > +/// Creates a new [`CStr`] from a string literal. > +/// > +/// The string literal should not contain any `NUL` bytes. > +/// > +/// # Examples > +/// > +/// ``` > +/// # use kernel::c_str; > +/// # use kernel::str::CStr; > +/// const MY_CSTR: &CStr = c_str!("My awesome CStr!"); > +/// ``` > +#[macro_export] > +macro_rules! c_str { > + ($str:expr) => {{ > + const S: &str = concat!($str, "\0"); > + const C: &$crate::str::CStr = $crate::str::CStr::from_bytes_with_nul_unwrap(S.as_bytes()); > + C > + }}; > +}
+#[macro_export] +macro_rules! c_str { + ($str:expr) => {{ + const S: &str = concat!($str, "\0"); + const C: &$crate::str::CStr = match $crate::str::CStr::from_bytes_with_nul(S.as_bytes()) { + Ok(v) => v, + Err(_) => panic!("string contains interior NUL"), + }; + C + }}; +}
> + > #[cfg(test)] > mod tests { > use super::*;
| |