diff --git a/CHANGELOG.md b/CHANGELOG.md index f489ab376..1c1d1d53f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Implementations for the trait `EqStrUntilNul` now allow `?Sized` inputs. This means that you can write `some_cstr16.eq_str_until_nul("test")` instead of `some_cstr16.eq_str_until_nul(&"test")` now. +- Added `TryFrom` implementation for `CStr8`. ## uefi-macros - [Unreleased] diff --git a/uefi/src/data_types/strs.rs b/uefi/src/data_types/strs.rs index 014267a20..437f6d9a9 100644 --- a/uefi/src/data_types/strs.rs +++ b/uefi/src/data_types/strs.rs @@ -1,5 +1,6 @@ use super::chars::{Char16, Char8, NUL_16, NUL_8}; use super::UnalignedSlice; +use core::ffi::CStr; use core::fmt; use core::iter::Iterator; use core::mem::MaybeUninit; @@ -58,6 +59,11 @@ pub enum FromStrWithBufError { /// This type is largely inspired by [`core::ffi::CStr`] with the exception that all characters are /// guaranteed to be 8 bit long. /// +/// A [`CStr8`] can be constructed from a [`core::ffi::CStr`] via a `try_from` call: +/// ```ignore +/// let cstr8: &CStr8 = TryFrom::try_from(cstr).unwrap(); +/// ``` +/// /// For convenience, a [`CStr8`] is comparable with [`core::str`] and /// `alloc::string::String` from the standard library through the trait [`EqStrUntilNul`]. #[repr(transparent)] @@ -156,6 +162,14 @@ impl + ?Sized> EqStrUntilNul for CStr8 { } } +impl<'a> TryFrom<&'a CStr> for &'a CStr8 { + type Error = FromSliceWithNulError; + + fn try_from(cstr: &'a CStr) -> Result { + CStr8::from_bytes_with_nul(cstr.to_bytes_with_nul()) + } +} + /// An UCS-2 null-terminated string. /// /// This type is largely inspired by [`core::ffi::CStr`] with the exception that all characters are @@ -453,6 +467,16 @@ mod tests { use crate::alloc::string::String; use uefi_macros::{cstr16, cstr8}; + // Tests if our CStr8 type can be constructed from a valid core::ffi::CStr + #[test] + fn test_cstr8_from_cstr() { + let msg = "hello world\0"; + let cstr = unsafe { CStr::from_ptr(msg.as_ptr().cast()) }; + let cstr8: &CStr8 = TryFrom::try_from(cstr).unwrap(); + assert!(cstr8.eq_str_until_nul(msg)); + assert!(msg.eq_str_until_nul(cstr8)); + } + #[test] fn test_cstr16_num_bytes() { let s = CStr16::from_u16_with_nul(&[65, 66, 67, 0]).unwrap();