History

rust: str: add conversion from `CStr` to `CString`

These methods can be used to copy the data in a temporary c string into a separate allocation, so that it can be accessed later even if the original is deallocated. The API in this change mirrors the standard library API for the `&str` and `String` types. The `ToOwned` trait is not implemented because it assumes that allocations are infallible.

Alice Ryhl committed 3 years ago

Commit 66bd7531 parent 4a590811 file · +22 −0Browse files

Showing the changes to rust/kernel (1 of 1 file). Show all

Unified · Split

rust/kernel/str.rs+22−0
@@ -2,6 +2,7 @@ · 1 unmodified line
2 2
3//! String representations.3//! String representations.
4 4
5use alloc::alloc::AllocError;
5use alloc::vec::Vec;6use alloc::vec::Vec;
6use core::fmt::{self, Write};7use core::fmt::{self, Write};
7use core::ops::{self, Deref, Index};8use core::ops::{self, Deref, Index};
@@ -199,6 +200,12 @@ impl CStr { · 191 unmodified lines
199 pub unsafe fn as_str_unchecked(&self) -> &str {200 pub unsafe fn as_str_unchecked(&self) -> &str {
200 unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }201 unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
201 }202 }
203
204 /// Convert this [`CStr`] into a [`CString`] by allocating memory and
205 /// copying over the string data.
206 pub fn to_cstring(&self) -> Result<CString, AllocError> {
207 CString::try_from(self)
208 }
202}209}
203 210
204impl fmt::Display for CStr {211impl fmt::Display for CStr {
@@ -584,6 +591,21 @@ impl Deref for CString { · 379 unmodified lines
584 }591 }
585}592}
586 593
594impl<'a> TryFrom<&'a CStr> for CString {
595 type Error = AllocError;
596
597 fn try_from(cstr: &'a CStr) -> Result<CString, AllocError> {
598 let mut buf = Vec::new();
599
600 buf.try_extend_from_slice(cstr.as_bytes_with_nul())
601 .map_err(|_| AllocError)?;
602
603 // INVARIANT: The `CStr` and `CString` types have the same invariants for
604 // the string data, and we copied it over without changes.
605 Ok(CString { buf })
606 }
607}
608
587/// A convenience alias for [`core::format_args`].609/// A convenience alias for [`core::format_args`].
588#[macro_export]610#[macro_export]
589macro_rules! fmt {611macro_rules! fmt {