From 10a7108d4bd411166a7b4484bda8894dc3f0f04b Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Fri, 4 Jul 2025 16:14:56 -0400 Subject: [PATCH] rust: str: add `CStr` methods matching `core::ffi::CStr` Prepare for replacing `CStr` with `core::ffi::CStr` by soft-deprecating methods which don't exist on `core::ffi::CStr`. We could keep `as_bytes{,_with_nul}` through an extension trait but seeing as we have to introduce `as_char_ptr_in_const_context` as a free function, we may as well introduce `to_bytes{,_with_nul}` here to allow downstream code to migrate in one cycle rather than two. Link: https://github.com/Rust-for-Linux/linux/issues/1075 Signed-off-by: Tamir Duberstein Reviewed-by: Benno Lossin Reviewed-by: Alice Ryhl Link: https://lore.kernel.org/r/20250704-core-cstr-prepare-v1-5-a91524037783@gmail.com [ Reworded title. - Miguel ] Signed-off-by: Miguel Ojeda --- rust/kernel/str.rs | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs index f326f0c40ab04..cbb357fc0111c 100644 --- a/rust/kernel/str.rs +++ b/rust/kernel/str.rs @@ -175,6 +175,15 @@ macro_rules! b_str { }}; } +/// Returns a C pointer to the string. +// It is a free function rather than a method on an extension trait because: +// +// - error[E0379]: functions in trait impls cannot be declared const +#[inline] +pub const fn as_char_ptr_in_const_context(c_str: &CStr) -> *const c_char { + c_str.0.as_ptr() +} + /// Possible errors when using conversion functions in [`CStr`]. #[derive(Debug, Clone, Copy)] pub enum CStrConvertError { @@ -294,23 +303,45 @@ impl CStr { } /// Returns a C pointer to the string. + /// + /// Using this function in a const context is deprecated in favor of + /// [`as_char_ptr_in_const_context`] in preparation for replacing `CStr` with `core::ffi::CStr` + /// which does not have this method. #[inline] pub const fn as_char_ptr(&self) -> *const c_char { - self.0.as_ptr() + as_char_ptr_in_const_context(self) } /// Convert the string to a byte slice without the trailing `NUL` byte. #[inline] - pub fn as_bytes(&self) -> &[u8] { + pub fn to_bytes(&self) -> &[u8] { &self.0[..self.len()] } + /// Convert the string to a byte slice without the trailing `NUL` byte. + /// + /// This function is deprecated in favor of [`Self::to_bytes`] in preparation for replacing + /// `CStr` with `core::ffi::CStr` which does not have this method. + #[inline] + pub fn as_bytes(&self) -> &[u8] { + self.to_bytes() + } + /// Convert the string to a byte slice containing the trailing `NUL` byte. #[inline] - pub const fn as_bytes_with_nul(&self) -> &[u8] { + pub const fn to_bytes_with_nul(&self) -> &[u8] { &self.0 } + /// Convert the string to a byte slice containing the trailing `NUL` byte. + /// + /// This function is deprecated in favor of [`Self::to_bytes_with_nul`] in preparation for + /// replacing `CStr` with `core::ffi::CStr` which does not have this method. + #[inline] + pub const fn as_bytes_with_nul(&self) -> &[u8] { + self.to_bytes_with_nul() + } + /// Yields a [`&str`] slice if the [`CStr`] contains valid UTF-8. /// /// If the contents of the [`CStr`] are valid UTF-8 data, this -- 2.47.2