diff options
Diffstat (limited to 'rust/kernel/str.rs')
| -rw-r--r-- | rust/kernel/str.rs | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs index cd3d2a6cf1fc..c41607b2e4fe 100644 --- a/rust/kernel/str.rs +++ b/rust/kernel/str.rs @@ -2,6 +2,7 @@ //! String representations. +use alloc::alloc::AllocError; use alloc::vec::Vec; use core::fmt::{self, Write}; use core::ops::{self, Deref, Index}; @@ -199,6 +200,12 @@ impl CStr { pub unsafe fn as_str_unchecked(&self) -> &str { unsafe { core::str::from_utf8_unchecked(self.as_bytes()) } } + + /// Convert this [`CStr`] into a [`CString`] by allocating memory and + /// copying over the string data. + pub fn to_cstring(&self) -> Result<CString, AllocError> { + CString::try_from(self) + } } impl fmt::Display for CStr { @@ -206,6 +213,7 @@ impl fmt::Display for CStr { /// /// ``` /// # use kernel::c_str; + /// # use kernel::fmt; /// # use kernel::str::CStr; /// # use kernel::str::CString; /// let penguin = c_str!("🐧"); @@ -234,6 +242,7 @@ impl fmt::Debug for CStr { /// /// ``` /// # use kernel::c_str; + /// # use kernel::fmt; /// # use kernel::str::CStr; /// # use kernel::str::CString; /// let penguin = c_str!("🐧"); @@ -522,7 +531,7 @@ impl fmt::Write for Formatter { /// # Examples /// /// ``` -/// use kernel::str::CString; +/// use kernel::{str::CString, fmt}; /// /// let s = CString::try_from_fmt(fmt!("{}{}{}", "abc", 10, 20)).unwrap(); /// assert_eq!(s.as_bytes_with_nul(), "abc1020\0".as_bytes()); @@ -584,6 +593,21 @@ impl Deref for CString { } } +impl<'a> TryFrom<&'a CStr> for CString { + type Error = AllocError; + + fn try_from(cstr: &'a CStr) -> Result<CString, AllocError> { + let mut buf = Vec::new(); + + buf.try_extend_from_slice(cstr.as_bytes_with_nul()) + .map_err(|_| AllocError)?; + + // INVARIANT: The `CStr` and `CString` types have the same invariants for + // the string data, and we copied it over without changes. + Ok(CString { buf }) + } +} + /// A convenience alias for [`core::format_args`]. #[macro_export] macro_rules! fmt { |