|
2 | 2 |
|
3 | 3 | //! String representations.
|
4 | 4 |
|
| 5 | +use alloc::alloc::AllocError; |
5 | 6 | use alloc::vec::Vec;
|
6 | 7 | use core::fmt::{self, Write};
|
7 | 8 | use core::ops::{self, Deref, Index};
|
@@ -199,6 +200,12 @@ impl CStr {
|
199 | 200 | pub unsafe fn as_str_unchecked(&self) -> &str {
|
200 | 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 |
|
204 | 211 | impl fmt::Display for CStr {
|
@@ -584,6 +591,21 @@ impl Deref for CString {
|
584 | 591 | }
|
585 | 592 | }
|
586 | 593 |
|
| 594 | +impl<'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 | 609 | /// A convenience alias for [`core::format_args`].
|
588 | 610 | #[macro_export]
|
589 | 611 | macro_rules! fmt {
|
|
0 commit comments