@@ -35,17 +35,20 @@ pub mod ffi;
35
35
mod idna;
36
36
pub use idna:: Idna ;
37
37
38
+ use derive_more:: { Display , Error } ;
38
39
use std:: { borrow, fmt, hash, ops, os:: raw:: c_uint} ;
39
- use thiserror:: Error ;
40
40
41
41
extern crate alloc;
42
42
#[ cfg( feature = "serde" ) ]
43
43
extern crate serde;
44
44
45
- #[ derive( Error , Debug , PartialEq , Eq ) ]
46
- pub enum Error {
47
- #[ error( "Invalid url: \" {0}\" " ) ]
48
- ParseUrl ( String ) ,
45
+ /// Error type of [`Url::parse`].
46
+ #[ derive( Debug , Display , Error , PartialEq , Eq ) ]
47
+ #[ display( bound = "Input: std::fmt::Debug" ) ]
48
+ #[ display( fmt = "Invalid url: {input:?}" ) ]
49
+ pub struct ParseUrlError < Input > {
50
+ /// The invalid input that caused the error.
51
+ pub input : Input ,
49
52
}
50
53
51
54
/// Defines the type of the host.
@@ -161,23 +164,26 @@ impl Url {
161
164
/// .expect("This is a valid URL. Should have parsed it.");
162
165
/// assert_eq!(out.protocol(), "https:");
163
166
/// ```
164
- pub fn parse ( input : & str , base : Option < & str > ) -> Result < Url , Error > {
167
+ pub fn parse < Input > ( input : Input , base : Option < & str > ) -> Result < Url , ParseUrlError < Input > >
168
+ where
169
+ Input : AsRef < str > ,
170
+ {
165
171
let url_aggregator = match base {
166
172
Some ( base) => unsafe {
167
173
ffi:: ada_parse_with_base (
168
- input. as_ptr ( ) . cast ( ) ,
169
- input. len ( ) ,
174
+ input. as_ref ( ) . as_ptr ( ) . cast ( ) ,
175
+ input. as_ref ( ) . len ( ) ,
170
176
base. as_ptr ( ) . cast ( ) ,
171
177
base. len ( ) ,
172
178
)
173
179
} ,
174
- None => unsafe { ffi:: ada_parse ( input. as_ptr ( ) . cast ( ) , input. len ( ) ) } ,
180
+ None => unsafe { ffi:: ada_parse ( input. as_ref ( ) . as_ptr ( ) . cast ( ) , input. as_ref ( ) . len ( ) ) } ,
175
181
} ;
176
182
177
183
if unsafe { ffi:: ada_is_valid ( url_aggregator) } {
178
184
Ok ( url_aggregator. into ( ) )
179
185
} else {
180
- Err ( Error :: ParseUrl ( input. to_owned ( ) ) )
186
+ Err ( ParseUrlError { input } )
181
187
}
182
188
}
183
189
@@ -686,26 +692,26 @@ impl fmt::Debug for Url {
686
692
}
687
693
}
688
694
689
- impl TryFrom < & str > for Url {
690
- type Error = Error ;
695
+ impl < ' input > TryFrom < & ' input str > for Url {
696
+ type Error = ParseUrlError < & ' input str > ;
691
697
692
- fn try_from ( value : & str ) -> Result < Self , Self :: Error > {
698
+ fn try_from ( value : & ' input str ) -> Result < Self , Self :: Error > {
693
699
Self :: parse ( value, None )
694
700
}
695
701
}
696
702
697
703
impl TryFrom < String > for Url {
698
- type Error = Error ;
704
+ type Error = ParseUrlError < String > ;
699
705
700
706
fn try_from ( value : String ) -> Result < Self , Self :: Error > {
701
- Self :: parse ( & value, None )
707
+ Self :: parse ( value, None )
702
708
}
703
709
}
704
710
705
- impl TryFrom < & String > for Url {
706
- type Error = Error ;
711
+ impl < ' input > TryFrom < & ' input String > for Url {
712
+ type Error = ParseUrlError < & ' input String > ;
707
713
708
- fn try_from ( value : & String ) -> Result < Self , Self :: Error > {
714
+ fn try_from ( value : & ' input String ) -> Result < Self , Self :: Error > {
709
715
Self :: parse ( value, None )
710
716
}
711
717
}
@@ -730,10 +736,12 @@ impl fmt::Display for Url {
730
736
}
731
737
732
738
impl std:: str:: FromStr for Url {
733
- type Err = Error ;
739
+ type Err = ParseUrlError < Box < str > > ;
734
740
735
741
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
736
- Self :: parse ( s, None )
742
+ Self :: parse ( s, None ) . map_err ( |ParseUrlError { input } | ParseUrlError {
743
+ input : input. into ( ) ,
744
+ } )
737
745
}
738
746
}
739
747
@@ -789,7 +797,7 @@ mod test {
789
797
dbg ! ( & url) ;
790
798
let error = url. unwrap_err ( ) ;
791
799
assert_eq ! ( error. to_string( ) , r#"Invalid url: "this is not a url""# ) ;
792
- assert ! ( matches! ( error, Error :: ParseUrl ( _ ) ) ) ;
800
+ assert_eq ! ( error. input , "this is not a url" ) ;
793
801
}
794
802
795
803
#[ test]
0 commit comments