1
1
use std:: { fmt, mem} ;
2
- use std:: ascii:: AsciiExt ;
3
2
use std:: borrow:: Borrow ;
3
+ use std:: error:: Error ;
4
+ use std:: any:: Any ;
4
5
use std:: str:: FromStr ;
5
6
use std:: ops:: { Deref , DerefMut , Add , Index , IndexMut } ;
6
7
use std:: iter:: FromIterator ;
@@ -93,15 +94,7 @@ impl AsciiString {
93
94
pub unsafe fn from_ascii_unchecked < B > ( bytes : B ) -> Self
94
95
where B : Into < Vec < u8 > >
95
96
{
96
- let bytes: Vec < u8 > = bytes. into ( ) ;
97
- let vec = Vec :: from_raw_parts ( bytes. as_ptr ( ) as * mut AsciiChar ,
98
- bytes. len ( ) ,
99
- bytes. capacity ( ) ) ;
100
-
101
- // We forget `src` to avoid freeing it at the end of the scope.
102
- // Otherwise, the returned `AsciiString` would point to freed memory.
103
- mem:: forget ( bytes) ;
104
- AsciiString { vec : vec }
97
+ AsciiString { vec : mem:: transmute ( bytes. into ( ) ) }
105
98
}
106
99
107
100
/// Converts anything that can represent a byte buffer into an `AsciiString`.
@@ -112,21 +105,17 @@ impl AsciiString {
112
105
/// # Examples
113
106
/// ```
114
107
/// # use ascii::AsciiString;
115
- /// let foo = AsciiString::from_ascii("foo").unwrap();
116
- /// let err = AsciiString::from_ascii("Ŋ");
108
+ /// let foo = AsciiString::from_ascii("foo".to_string() ).unwrap();
109
+ /// let err = AsciiString::from_ascii("Ŋ".to_string()).unwrap_err( );
117
110
/// assert_eq!(foo.as_str(), "foo");
118
- /// assert_eq!(err, Err( "Ŋ") );
111
+ /// assert_eq!(err.into_source(), "Ŋ");
119
112
/// ```
120
- pub fn from_ascii < B > ( bytes : B ) -> Result < AsciiString , B >
121
- where B : Into < Vec < u8 > > + AsRef < [ u8 ] >
122
- {
123
- unsafe {
124
- if bytes. as_ref ( ) . is_ascii ( ) {
125
- Ok ( AsciiString :: from_ascii_unchecked ( bytes) )
126
- } else {
127
- Err ( bytes)
128
- }
129
- }
113
+ pub fn from_ascii < B : Into < Vec < u8 > > + AsRef < [ u8 ] > >
114
+ ( bytes : B ) -> Result < AsciiString , FromAsciiError < B > > {
115
+ unsafe { match bytes. as_ref ( ) . as_ascii_str ( ) {
116
+ Ok ( _) => Ok ( AsciiString :: from_ascii_unchecked ( bytes) ) ,
117
+ Err ( e) => Err ( FromAsciiError { error : e, owner : bytes} ) ,
118
+ } }
130
119
}
131
120
132
121
/// Pushes the given ASCII string onto this ASCII string buffer.
@@ -536,19 +525,69 @@ impl<T> IndexMut<T> for AsciiString where AsciiStr: IndexMut<T> {
536
525
}
537
526
538
527
528
+ /// A possible error value when converting an `AsciiString` from a byte vector or string.
529
+ /// It wraps an `AsAsciiStrError` which you can get through the `ascii_error()` method.
530
+ ///
531
+ /// This is the error type for `AsciiString::from_ascii()` and `IntoAsciiString::into_ascii_string()``
532
+ /// They will never clone or touch the content of the original type;
533
+ /// It can be extracted by the `into_source` method.
534
+ ///
535
+ /// #Examples
536
+ /// ```
537
+ /// # use ascii::IntoAsciiString;
538
+ /// let err = "bø!".to_string().into_ascii_string().unwrap_err();
539
+ /// assert_eq!(err.ascii_error().valid_up_to(), 1);
540
+ /// assert_eq!(err.into_source(), "bø!".to_string());
541
+ /// ```
542
+ #[ derive( Clone , Copy , PartialEq , Eq ) ]
543
+ pub struct FromAsciiError < O > {
544
+ error : AsAsciiStrError ,
545
+ owner : O ,
546
+ }
547
+ impl < O > FromAsciiError < O > {
548
+ /// Get the position of the first non-ASCII byte or character.
549
+ pub fn ascii_error ( & self ) -> AsAsciiStrError {
550
+ self . error
551
+ }
552
+ /// Get back the original, unmodified type.
553
+ pub fn into_source ( self ) -> O {
554
+ self . owner
555
+ }
556
+ }
557
+ impl < O > fmt:: Debug for FromAsciiError < O > {
558
+ fn fmt ( & self , fmtr : & mut fmt:: Formatter ) -> fmt:: Result {
559
+ fmt:: Debug :: fmt ( & self . error , fmtr)
560
+ }
561
+ }
562
+ impl < O > fmt:: Display for FromAsciiError < O > {
563
+ fn fmt ( & self , fmtr : & mut fmt:: Formatter ) -> fmt:: Result {
564
+ fmt:: Display :: fmt ( & self . error , fmtr)
565
+ }
566
+ }
567
+ impl < O : Any > Error for FromAsciiError < O > {
568
+ fn description ( & self ) -> & str {
569
+ self . error . description ( )
570
+ }
571
+ /// Always returns an `AsAsciiStrError`
572
+ fn cause ( & self ) -> Option < & Error > {
573
+ Some ( & self . error as & Error )
574
+ }
575
+ }
576
+
577
+
539
578
/// Convert vectors into `AsciiString`.
540
579
pub trait IntoAsciiString : Sized {
541
580
/// Convert to `AsciiString` without checking for non-ASCII characters.
542
581
unsafe fn into_ascii_string_unchecked ( self ) -> AsciiString ;
543
582
/// Convert to `AsciiString`.
544
- fn into_ascii_string ( self ) -> Result < AsciiString , Self > ;
583
+ fn into_ascii_string ( self ) -> Result < AsciiString , FromAsciiError < Self > > ;
545
584
}
546
585
547
586
impl IntoAsciiString for AsciiString {
548
587
unsafe fn into_ascii_string_unchecked ( self ) -> AsciiString {
549
588
self
550
589
}
551
- fn into_ascii_string ( self ) -> Result < AsciiString , Self > {
590
+ fn into_ascii_string ( self ) -> Result < Self , FromAsciiError < Self > > {
552
591
Ok ( self )
553
592
}
554
593
}
@@ -557,7 +596,7 @@ impl IntoAsciiString for Vec<AsciiChar> {
557
596
unsafe fn into_ascii_string_unchecked ( self ) -> AsciiString {
558
597
AsciiString :: from ( self )
559
598
}
560
- fn into_ascii_string ( self ) -> Result < AsciiString , Self > {
599
+ fn into_ascii_string ( self ) -> Result < AsciiString , FromAsciiError < Self > > {
561
600
Ok ( AsciiString :: from ( self ) )
562
601
}
563
602
}
@@ -566,7 +605,7 @@ impl IntoAsciiString for Vec<u8> {
566
605
unsafe fn into_ascii_string_unchecked ( self ) -> AsciiString {
567
606
AsciiString :: from_ascii_unchecked ( self )
568
607
}
569
- fn into_ascii_string ( self ) -> Result < AsciiString , Self > {
608
+ fn into_ascii_string ( self ) -> Result < AsciiString , FromAsciiError < Self > > {
570
609
AsciiString :: from_ascii ( self )
571
610
}
572
611
}
@@ -575,7 +614,7 @@ impl IntoAsciiString for String {
575
614
unsafe fn into_ascii_string_unchecked ( self ) -> AsciiString {
576
615
self . into_bytes ( ) . into_ascii_string_unchecked ( )
577
616
}
578
- fn into_ascii_string ( self ) -> Result < AsciiString , Self > {
617
+ fn into_ascii_string ( self ) -> Result < AsciiString , FromAsciiError < Self > > {
579
618
AsciiString :: from_ascii ( self )
580
619
}
581
620
}
@@ -606,14 +645,9 @@ mod tests {
606
645
}
607
646
608
647
#[ test]
609
- fn fmt_display_ascii_string ( ) {
648
+ fn fmt_ascii_string ( ) {
610
649
let s = "abc" . to_string ( ) . into_ascii_string ( ) . unwrap ( ) ;
611
650
assert_eq ! ( format!( "{}" , s) , "abc" . to_string( ) ) ;
612
- }
613
-
614
- #[ test]
615
- fn fmt_debug_ascii_string ( ) {
616
- let s = "abc" . to_string ( ) . into_ascii_string ( ) . unwrap ( ) ;
617
651
assert_eq ! ( format!( "{:?}" , s) , "\" abc\" " . to_string( ) ) ;
618
652
}
619
653
}
0 commit comments