11use std:: borrow:: { Borrow , Cow } ;
2+ use std:: error:: Error as StdError ;
23use std:: fmt;
34use std:: hash:: { Hash , Hasher } ;
45use std:: mem;
@@ -10,7 +11,38 @@ use std::str::{self, FromStr};
1011use ascii:: { AsAsciiStr , AsAsciiStrError , AsciiStr } ;
1112
1213use crate :: array:: Array ;
13- use crate :: errors:: Result ;
14+
15+ #[ derive( Clone , Copy , PartialEq , Eq , Debug ) ]
16+ pub enum StringError {
17+ InternalNull ,
18+ InsufficientCapacity ,
19+ AsciiError ( AsAsciiStrError ) ,
20+ #[ doc( hidden) ]
21+ __Incomplete,
22+ }
23+
24+ impl From < AsAsciiStrError > for StringError {
25+ fn from ( err : AsAsciiStrError ) -> Self {
26+ StringError :: AsciiError ( err)
27+ }
28+ }
29+
30+ impl StdError for StringError {
31+ fn description ( & self ) -> & str {
32+ match self {
33+ StringError :: InternalNull => "variable length string with internal null" ,
34+ StringError :: InsufficientCapacity => "insufficient capacity for fixed sized string" ,
35+ StringError :: AsciiError ( err) => err. description ( ) ,
36+ _ => "" ,
37+ }
38+ }
39+ }
40+
41+ impl fmt:: Display for StringError {
42+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
43+ write ! ( f, "string error: {}" , self . description( ) )
44+ }
45+ }
1446
1547// ================================================================================
1648
@@ -221,12 +253,10 @@ impl VarLenAscii {
221253 Self :: from_bytes ( bytes. as_ref ( ) )
222254 }
223255
224- pub fn from_ascii < B : ?Sized + AsRef < [ u8 ] > > ( bytes : & B ) -> Result < Self > {
256+ pub fn from_ascii < B : ?Sized + AsRef < [ u8 ] > > ( bytes : & B ) -> Result < Self , StringError > {
225257 let bytes = bytes. as_ref ( ) ;
226258 if !bytes. iter ( ) . all ( |& c| c != 0 ) {
227- bail ! ( "Variable length ASCII string with internal null: {:?}" , unsafe {
228- str :: from_utf8_unchecked( bytes)
229- } ) ;
259+ return Err ( StringError :: InternalNull ) ;
230260 }
231261 let s = AsciiStr :: from_ascii ( bytes) ?;
232262 unsafe { Ok ( Self :: from_bytes ( s. as_bytes ( ) ) ) }
@@ -239,7 +269,7 @@ impl AsAsciiStr for VarLenAscii {
239269 AsciiStr :: from_ascii_unchecked ( self . as_bytes ( ) )
240270 }
241271
242- fn as_ascii_str ( & self ) -> :: std :: result :: Result < & AsciiStr , AsAsciiStrError > {
272+ fn as_ascii_str ( & self ) -> Result < & AsciiStr , AsAsciiStrError > {
243273 AsciiStr :: from_ascii ( self . as_bytes ( ) )
244274 }
245275}
@@ -322,11 +352,14 @@ impl VarLenUnicode {
322352}
323353
324354impl FromStr for VarLenUnicode {
325- type Err = crate :: errors :: Error ;
355+ type Err = StringError ;
326356
327- fn from_str ( s : & str ) -> Result < Self > {
328- ensure ! ( s. chars( ) . all( |c| c != '\0' ) , "Variable length unicode string with internal null" ) ;
329- unsafe { Ok ( Self :: from_bytes ( s. as_bytes ( ) ) ) }
357+ fn from_str ( s : & str ) -> Result < Self , <Self as FromStr >:: Err > {
358+ if s. chars ( ) . all ( |c| c != '\0' ) {
359+ unsafe { Ok ( Self :: from_bytes ( s. as_bytes ( ) ) ) }
360+ } else {
361+ Err ( StringError :: InternalNull )
362+ }
330363 }
331364}
332365
@@ -342,9 +375,9 @@ impl<A: Array<Item = u8>> Clone for FixedAscii<A> {
342375 #[ inline]
343376 fn clone ( & self ) -> Self {
344377 unsafe {
345- let mut buf: A = mem:: uninitialized ( ) ;
346- ptr:: copy_nonoverlapping ( self . buf . as_ptr ( ) , buf. as_mut_ptr ( ) , A :: capacity ( ) ) ;
347- FixedAscii { buf }
378+ let mut buf = mem:: MaybeUninit :: < A > :: uninit ( ) ;
379+ ptr:: copy_nonoverlapping ( self . buf . as_ptr ( ) , buf. as_mut_ptr ( ) as * mut _ , A :: capacity ( ) ) ;
380+ FixedAscii { buf : buf . assume_init ( ) }
348381 }
349382 }
350383}
@@ -403,12 +436,12 @@ impl<A: Array<Item = u8>> FixedAscii<A> {
403436 Self :: from_bytes ( bytes. as_ref ( ) )
404437 }
405438
406- pub fn from_ascii < B : ?Sized + AsRef < [ u8 ] > > ( bytes : & B ) -> Result < Self > {
439+ pub fn from_ascii < B : ?Sized + AsRef < [ u8 ] > > ( bytes : & B ) -> Result < Self , StringError > {
407440 let bytes = bytes. as_ref ( ) ;
408- ensure ! ( bytes. len( ) <= A :: capacity( ) , "Insufficient capacity for fixed-size ASCII string" ) ;
409- let s = AsciiStr :: from_ascii ( bytes ) . map_err ( |_| {
410- format ! ( "Invalid ASCII string: `{}`" , unsafe { str :: from_utf8_unchecked ( bytes ) } )
411- } ) ?;
441+ if bytes. len ( ) > A :: capacity ( ) {
442+ return Err ( StringError :: InsufficientCapacity ) ;
443+ }
444+ let s = AsciiStr :: from_ascii ( bytes ) ?;
412445 unsafe { Ok ( Self :: from_bytes ( s. as_bytes ( ) ) ) }
413446 }
414447}
@@ -419,7 +452,7 @@ impl<A: Array<Item = u8>> AsAsciiStr for FixedAscii<A> {
419452 AsciiStr :: from_ascii_unchecked ( self . as_bytes ( ) )
420453 }
421454
422- fn as_ascii_str ( & self ) -> :: std :: result :: Result < & AsciiStr , AsAsciiStrError > {
455+ fn as_ascii_str ( & self ) -> Result < & AsciiStr , AsAsciiStrError > {
423456 AsciiStr :: from_ascii ( self . as_bytes ( ) )
424457 }
425458}
@@ -436,9 +469,9 @@ impl<A: Array<Item = u8>> Clone for FixedUnicode<A> {
436469 #[ inline]
437470 fn clone ( & self ) -> Self {
438471 unsafe {
439- let mut buf: A = mem:: uninitialized ( ) ;
440- ptr:: copy_nonoverlapping ( self . buf . as_ptr ( ) , buf. as_mut_ptr ( ) , A :: capacity ( ) ) ;
441- FixedUnicode { buf }
472+ let mut buf = mem:: MaybeUninit :: < A > :: uninit ( ) ;
473+ ptr:: copy_nonoverlapping ( self . buf . as_ptr ( ) , buf. as_mut_ptr ( ) as * mut _ , A :: capacity ( ) ) ;
474+ FixedUnicode { buf : buf . assume_init ( ) }
442475 }
443476 }
444477}
@@ -507,14 +540,14 @@ impl<A> FromStr for FixedUnicode<A>
507540where
508541 A : Array < Item = u8 > ,
509542{
510- type Err = crate :: errors :: Error ;
543+ type Err = StringError ;
511544
512- fn from_str ( s : & str ) -> Result < Self > {
513- ensure ! (
514- s. as_bytes( ) . len ( ) <= A :: capacity ( ) ,
515- "Insufficient capacity for fixed-size unicode string"
516- ) ;
517- unsafe { Ok ( Self :: from_bytes ( s . as_bytes ( ) ) ) }
545+ fn from_str ( s : & str ) -> Result < Self , < Self as FromStr > :: Err > {
546+ if s . as_bytes ( ) . len ( ) <= A :: capacity ( ) {
547+ unsafe { Ok ( Self :: from_bytes ( s. as_bytes ( ) ) ) }
548+ } else {
549+ Err ( StringError :: InsufficientCapacity )
550+ }
518551 }
519552}
520553
0 commit comments