3636
3737extern crate alloc;
3838
39- use alloc:: string:: FromUtf8Error as _FromUtf8Error ;
39+ use alloc:: string;
4040use alloc:: { boxed:: Box , string:: String , vec:: Vec } ;
4141use core:: convert:: Infallible ;
4242use core:: mem:: take;
@@ -133,21 +133,19 @@ impl<S: Zeroize + Clone> SecretBox<S> {
133133 }
134134}
135135
136- /// Error return from [`SecretString::from_utf8`] or [`SecretString::from_utf8_len`] .
136+ /// A possible error value when creating a [`SecretString`] from a UTF-8 byte vector .
137137///
138- /// This is like [`FromUtf8Error`] except it zeroizes its buffer on [`Drop`].
139- ///
140- /// [`FromUtf8Error`]: _FromUtf8Error
138+ /// This is like [`string::FromUtf8Error`] except it zeroizes its buffer on [`Drop`].
141139pub struct FromUtf8Error {
142- inner : Option < _FromUtf8Error > ,
140+ inner : Option < string :: FromUtf8Error > ,
143141}
144142
145143impl FromUtf8Error {
146- fn new ( inner : _FromUtf8Error ) -> Self {
144+ fn new ( inner : string :: FromUtf8Error ) -> Self {
147145 FromUtf8Error { inner : Some ( inner) }
148146 }
149147
150- /// See [`utf8_error`][_FromUtf8Error:: utf8_error].
148+ /// See [`string::FromUtf8Error:: utf8_error` ].
151149 pub fn utf8_error ( & self ) -> Utf8Error {
152150 // Panic safety: `take` is only called on moves.
153151 let Some ( err) = & self . inner else {
@@ -156,7 +154,7 @@ impl FromUtf8Error {
156154 err. utf8_error ( )
157155 }
158156
159- /// See [`into_bytes`][_FromUtf8Error:: into_bytes].
157+ /// See [`string::FromUtf8Error:: into_bytes` ].
160158 pub fn into_bytes ( mut self ) -> Vec < u8 > {
161159 // Panic safety: `take` is only called here and on `Drop`.
162160 let Some ( err) = self . inner . take ( ) else {
@@ -175,26 +173,37 @@ impl Drop for FromUtf8Error {
175173}
176174
177175impl SecretBox < str > {
176+ /// Create a [`SecretString`] from a UTF-8 byte buffer.
177+ ///
178178 /// See [`String::from_utf8`].
179- pub fn from_utf8 ( mut other : SecretBox < [ u8 ] > ) -> Result < Self , FromUtf8Error > {
180- Self :: try_from ( take ( & mut other. inner_secret ) . into_vec ( ) )
179+ pub fn from_utf8 ( buf : Vec < u8 > ) -> Result < Self , FromUtf8Error > {
180+ String :: from_utf8 ( buf)
181+ . map ( SecretBox :: from)
182+ . map_err ( FromUtf8Error :: new)
181183 }
182184
183- /// Like [`String::from_utf8`], except the buffer is truncated to `len` first.
184- pub fn from_utf8_len ( mut other : SecretBox < [ u8 ] > , len : usize ) -> Result < Self , FromUtf8Error > {
185- let mut buf = take ( & mut other. inner_secret ) . into_vec ( ) ;
186- buf. truncate ( len) ;
187- Self :: try_from ( buf)
185+ /// Create a [`SecretString`] from a <code>[SecretBox]<\[u8]></code>.
186+ ///
187+ /// This works like [`String::from_utf8`], i.e., it does not allocate but rather takes
188+ /// ownership of the backing buffer. Note that the result will have the whole buffer’s
189+ /// contents; to perform truncation, see [`SecretString::from_utf8_box_len`].
190+ pub fn from_utf8_box ( mut other : SecretBox < [ u8 ] > ) -> Result < Self , FromUtf8Error > {
191+ Self :: from_utf8 ( take ( & mut other. inner_secret ) . into_vec ( ) )
188192 }
189- }
190-
191- impl TryFrom < Vec < u8 > > for SecretBox < str > {
192- type Error = FromUtf8Error ;
193193
194- fn try_from ( value : Vec < u8 > ) -> Result < Self , Self :: Error > {
195- String :: from_utf8 ( value)
196- . map ( SecretBox :: from)
197- . map_err ( FromUtf8Error :: new)
194+ /// Create a [`SecretString`] from a portion of a <code>[SecretBox]<\[u8]></code>.
195+ ///
196+ /// This works like [`String::from_utf8`], except that the buffer is truncated to the specified
197+ /// length before the string is created. Note that the allocation is not resized; if the buffer
198+ /// is much larger than the resulting string, this is wasteful, and it is probably better to
199+ /// call [`SecretString::from`] on the slice to make a new allocation with only the needed size.
200+ pub fn from_utf8_box_len (
201+ mut other : SecretBox < [ u8 ] > ,
202+ len : usize ,
203+ ) -> Result < Self , FromUtf8Error > {
204+ let mut buf = take ( & mut other. inner_secret ) . into_vec ( ) ;
205+ buf. truncate ( len) ;
206+ Self :: from_utf8 ( buf)
198207 }
199208}
200209
0 commit comments