@@ -260,6 +260,32 @@ pub struct FromBytesWithNulError {
260260 kind : FromBytesWithNulErrorKind ,
261261}
262262
263+ /// An error indicating that a nul byte was not in the expected position.
264+ ///
265+ /// The vector used to create a [`CString`] must have one and only one nul byte,
266+ /// positioned at the end.
267+ ///
268+ /// This error is created by the [`from_vec_with_nul`] method on [`CString`].
269+ /// See its documentation for more.
270+ ///
271+ /// [`CString`]: struct.CString.html
272+ /// [`from_vec_with_nul`]: struct.CString.html#method.from_vec_with_nul
273+ ///
274+ /// # Examples
275+ ///
276+ /// ```
277+ /// #![feature(cstring_from_vec_with_nul)]
278+ /// use std::ffi::{CString, FromVecWithNulError};
279+ ///
280+ /// let _: FromVecWithNulError = CString::from_vec_with_nul(b"f\0oo".to_vec()).unwrap_err();
281+ /// ```
282+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
283+ #[ unstable( feature = "cstring_from_vec_with_nul" , issue = "73179" ) ]
284+ pub struct FromVecWithNulError {
285+ error_kind : FromBytesWithNulErrorKind ,
286+ bytes : Vec < u8 > ,
287+ }
288+
263289#[ derive( Clone , PartialEq , Eq , Debug ) ]
264290enum FromBytesWithNulErrorKind {
265291 InteriorNul ( usize ) ,
@@ -275,6 +301,59 @@ impl FromBytesWithNulError {
275301 }
276302}
277303
304+ #[ unstable( feature = "cstring_from_vec_with_nul" , issue = "73179" ) ]
305+ impl FromVecWithNulError {
306+ /// Returns a slice of [`u8`]s bytes that were attempted to convert to a [`CString`].
307+ ///
308+ /// # Examples
309+ ///
310+ /// Basic usage:
311+ ///
312+ /// ```
313+ /// #![feature(cstring_from_vec_with_nul)]
314+ /// use std::ffi::CString;
315+ ///
316+ /// // Some invalid bytes in a vector
317+ /// let bytes = b"f\0oo".to_vec();
318+ ///
319+ /// let value = CString::from_vec_with_nul(bytes.clone());
320+ ///
321+ /// assert_eq!(&bytes[..], value.unwrap_err().as_bytes());
322+ /// ```
323+ ///
324+ /// [`CString`]: struct.CString.html
325+ pub fn as_bytes ( & self ) -> & [ u8 ] {
326+ & self . bytes [ ..]
327+ }
328+
329+ /// Returns the bytes that were attempted to convert to a [`CString`].
330+ ///
331+ /// This method is carefully constructed to avoid allocation. It will
332+ /// consume the error, moving out the bytes, so that a copy of the bytes
333+ /// does not need to be made.
334+ ///
335+ /// # Examples
336+ ///
337+ /// Basic usage:
338+ ///
339+ /// ```
340+ /// #![feature(cstring_from_vec_with_nul)]
341+ /// use std::ffi::CString;
342+ ///
343+ /// // Some invalid bytes in a vector
344+ /// let bytes = b"f\0oo".to_vec();
345+ ///
346+ /// let value = CString::from_vec_with_nul(bytes.clone());
347+ ///
348+ /// assert_eq!(bytes, value.unwrap_err().into_bytes());
349+ /// ```
350+ ///
351+ /// [`CString`]: struct.CString.html
352+ pub fn into_bytes ( self ) -> Vec < u8 > {
353+ self . bytes
354+ }
355+ }
356+
278357/// An error indicating invalid UTF-8 when converting a [`CString`] into a [`String`].
279358///
280359/// `CString` is just a wrapper over a buffer of bytes with a nul
@@ -1039,6 +1118,23 @@ impl fmt::Display for FromBytesWithNulError {
10391118 }
10401119}
10411120
1121+ #[ unstable( feature = "cstring_from_vec_with_nul" , issue = "73179" ) ]
1122+ impl Error for FromVecWithNulError { }
1123+
1124+ #[ unstable( feature = "cstring_from_vec_with_nul" , issue = "73179" ) ]
1125+ impl fmt:: Display for FromVecWithNulError {
1126+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1127+ match self . error_kind {
1128+ FromBytesWithNulErrorKind :: InteriorNul ( pos) => {
1129+ write ! ( f, "data provided contains an interior nul byte at pos {}" , pos)
1130+ }
1131+ FromBytesWithNulErrorKind :: NotNulTerminated => {
1132+ write ! ( f, "data provided is not nul terminated" )
1133+ }
1134+ }
1135+ }
1136+ }
1137+
10421138impl IntoStringError {
10431139 /// Consumes this error, returning original [`CString`] which generated the
10441140 /// error.
0 commit comments