@@ -35,17 +35,20 @@ pub mod ffi;
3535mod idna;
3636pub use idna:: Idna ;
3737
38+ use derive_more:: { Display , Error } ;
3839use std:: { borrow, fmt, hash, ops, os:: raw:: c_uint} ;
39- use thiserror:: Error ;
4040
4141extern crate alloc;
4242#[ cfg( feature = "serde" ) ]
4343extern crate serde;
4444
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 ,
4952}
5053
5154/// Defines the type of the host.
@@ -161,23 +164,26 @@ impl Url {
161164 /// .expect("This is a valid URL. Should have parsed it.");
162165 /// assert_eq!(out.protocol(), "https:");
163166 /// ```
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+ {
165171 let url_aggregator = match base {
166172 Some ( base) => unsafe {
167173 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 ( ) ,
170176 base. as_ptr ( ) . cast ( ) ,
171177 base. len ( ) ,
172178 )
173179 } ,
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 ( ) ) } ,
175181 } ;
176182
177183 if unsafe { ffi:: ada_is_valid ( url_aggregator) } {
178184 Ok ( url_aggregator. into ( ) )
179185 } else {
180- Err ( Error :: ParseUrl ( input. to_owned ( ) ) )
186+ Err ( ParseUrlError { input } )
181187 }
182188 }
183189
@@ -686,26 +692,26 @@ impl fmt::Debug for Url {
686692 }
687693}
688694
689- impl TryFrom < & str > for Url {
690- type Error = Error ;
695+ impl < ' input > TryFrom < & ' input str > for Url {
696+ type Error = ParseUrlError < & ' input str > ;
691697
692- fn try_from ( value : & str ) -> Result < Self , Self :: Error > {
698+ fn try_from ( value : & ' input str ) -> Result < Self , Self :: Error > {
693699 Self :: parse ( value, None )
694700 }
695701}
696702
697703impl TryFrom < String > for Url {
698- type Error = Error ;
704+ type Error = ParseUrlError < String > ;
699705
700706 fn try_from ( value : String ) -> Result < Self , Self :: Error > {
701- Self :: parse ( & value, None )
707+ Self :: parse ( value, None )
702708 }
703709}
704710
705- impl TryFrom < & String > for Url {
706- type Error = Error ;
711+ impl < ' input > TryFrom < & ' input String > for Url {
712+ type Error = ParseUrlError < & ' input String > ;
707713
708- fn try_from ( value : & String ) -> Result < Self , Self :: Error > {
714+ fn try_from ( value : & ' input String ) -> Result < Self , Self :: Error > {
709715 Self :: parse ( value, None )
710716 }
711717}
@@ -730,10 +736,12 @@ impl fmt::Display for Url {
730736}
731737
732738impl std:: str:: FromStr for Url {
733- type Err = Error ;
739+ type Err = ParseUrlError < Box < str > > ;
734740
735741 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+ } )
737745 }
738746}
739747
@@ -789,7 +797,7 @@ mod test {
789797 dbg ! ( & url) ;
790798 let error = url. unwrap_err ( ) ;
791799 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" ) ;
793801 }
794802
795803 #[ test]
0 commit comments