@@ -73,6 +73,14 @@ assert!(data_url.fragment() == Some(""));
7373# run().unwrap();
7474```
7575
76+ ## Default Features
77+
78+ Versions `<= 2.5.2` of the crate have no default features. Versions `> 2.5.2` have the default feature 'std'.
79+ If you are upgrading across this boundary and you have specified `default-features = false`, then
80+ you will need to add the 'std' feature or the 'alloc' feature to your dependency.
81+ The 'std' feature has the same behavior as the previous versions. The 'alloc' feature
82+ provides no_std support.
83+
7684## Serde
7785
7886Enable the `serde` feature to include `Deserialize` and `Serialize` implementations for `url::Url`.
@@ -134,6 +142,7 @@ url = { version = "2", features = ["debugger_visualizer"] }
134142
135143*/
136144
145+ #![ no_std]
137146#![ doc( html_root_url = "https://docs.rs/url/2.5.2" ) ]
138147#![ cfg_attr(
139148 feature = "debugger_visualizer" ,
@@ -145,29 +154,48 @@ url = { version = "2", features = ["debugger_visualizer"] }
145154
146155pub use form_urlencoded;
147156
157+ // For forwards compatibility
158+ #[ cfg( feature = "std" ) ]
159+ extern crate std;
160+
161+ #[ macro_use]
162+ extern crate alloc;
163+
148164#[ cfg( feature = "serde" ) ]
149165extern crate serde;
150166
151167use crate :: host:: HostInternal ;
152- use crate :: parser:: {
153- to_u32, Context , Parser , SchemeType , PATH_SEGMENT , SPECIAL_PATH_SEGMENT , USERINFO ,
154- } ;
155- use percent_encoding:: { percent_decode, percent_encode, utf8_percent_encode} ;
156- use std:: borrow:: Borrow ;
157- use std:: cmp;
158- use std:: fmt:: { self , Write } ;
159- use std:: hash;
168+
169+ use crate :: net:: IpAddr ;
170+ #[ cfg( feature = "std" ) ]
160171#[ cfg( any( unix, windows, target_os = "redox" , target_os = "wasi" ) ) ]
161- use std:: io;
162- use std:: mem;
163- use std:: net:: IpAddr ;
172+ use crate :: net:: { SocketAddr , ToSocketAddrs } ;
173+ use crate :: parser:: { to_u32, Context , Parser , SchemeType , USERINFO } ;
174+ use alloc:: borrow:: ToOwned ;
175+ use alloc:: str;
176+ use alloc:: string:: { String , ToString } ;
177+ use core:: borrow:: Borrow ;
178+ use core:: convert:: TryFrom ;
179+ use core:: fmt:: Write ;
180+ use core:: ops:: { Range , RangeFrom , RangeTo } ;
181+ use core:: { cmp, fmt, hash, mem} ;
182+ use percent_encoding:: utf8_percent_encode;
183+ #[ cfg( feature = "std" ) ]
164184#[ cfg( any( unix, windows, target_os = "redox" , target_os = "wasi" ) ) ]
165- use std:: net :: { SocketAddr , ToSocketAddrs } ;
166- use std :: ops :: { Range , RangeFrom , RangeTo } ;
185+ use std:: io ;
186+ # [ cfg ( feature = "std" ) ]
167187use std:: path:: { Path , PathBuf } ;
168- use std:: str;
169188
170- use std:: convert:: TryFrom ;
189+ /// `std` version of `net`
190+ #[ cfg( feature = "std" ) ]
191+ pub ( crate ) mod net {
192+ pub use std:: net:: * ;
193+ }
194+ /// `no_std` nightly version of `net`
195+ #[ cfg( not( feature = "std" ) ) ]
196+ pub ( crate ) mod net {
197+ pub use core:: net:: * ;
198+ }
171199
172200pub use crate :: host:: Host ;
173201pub use crate :: origin:: { OpaqueOrigin , Origin } ;
@@ -1279,11 +1307,12 @@ impl Url {
12791307 /// })
12801308 /// }
12811309 /// ```
1310+ #[ cfg( feature = "std" ) ]
12821311 #[ cfg( any( unix, windows, target_os = "redox" , target_os = "wasi" ) ) ]
12831312 pub fn socket_addrs (
12841313 & self ,
12851314 default_port_number : impl Fn ( ) -> Option < u16 > ,
1286- ) -> io:: Result < Vec < SocketAddr > > {
1315+ ) -> io:: Result < alloc :: vec :: Vec < SocketAddr > > {
12871316 // Note: trying to avoid the Vec allocation by returning `impl AsRef<[SocketAddr]>`
12881317 // causes borrowck issues because the return value borrows `default_port_number`:
12891318 //
@@ -1353,7 +1382,11 @@ impl Url {
13531382 ///
13541383 /// ```
13551384 /// use url::Url;
1385+ ///
1386+ /// # #[cfg(feature = "std")]
13561387 /// # use std::error::Error;
1388+ /// # #[cfg(not(feature = "std"))]
1389+ /// # use core::error::Error;
13571390 ///
13581391 /// # fn run() -> Result<(), Box<dyn Error>> {
13591392 /// let url = Url::parse("https://example.com/foo/bar")?;
@@ -1767,7 +1800,11 @@ impl Url {
17671800 ///
17681801 /// ```
17691802 /// use url::Url;
1803+ ///
1804+ /// # #[cfg(feature = "std")]
17701805 /// # use std::error::Error;
1806+ /// # #[cfg(not(feature = "std"))]
1807+ /// # use core::error::Error;
17711808 ///
17721809 /// # fn run() -> Result<(), Box<dyn Error>> {
17731810 /// let mut url = Url::parse("ssh://example.net:2048/")?;
@@ -1786,7 +1823,11 @@ impl Url {
17861823 ///
17871824 /// ```rust
17881825 /// use url::Url;
1826+ ///
1827+ /// # #[cfg(feature = "std")]
17891828 /// # use std::error::Error;
1829+ /// # #[cfg(not(feature = "std"))]
1830+ /// # use core::error::Error;
17901831 ///
17911832 /// # fn run() -> Result<(), Box<dyn Error>> {
17921833 /// let mut url = Url::parse("https://example.org/")?;
@@ -2469,9 +2510,14 @@ impl Url {
24692510 /// # run().unwrap();
24702511 /// # }
24712512 /// ```
2472- #[ cfg( any( unix, windows, target_os = "redox" , target_os = "wasi" ) ) ]
2513+ ///
2514+ /// This method is only available if the `std` Cargo feature is enabled.
2515+ #[ cfg( all(
2516+ feature = "std" ,
2517+ any( unix, windows, target_os = "redox" , target_os = "wasi" )
2518+ ) ) ]
24732519 #[ allow( clippy:: result_unit_err) ]
2474- pub fn from_file_path < P : AsRef < Path > > ( path : P ) -> Result < Url , ( ) > {
2520+ pub fn from_file_path < P : AsRef < std :: path :: Path > > ( path : P ) -> Result < Url , ( ) > {
24752521 let mut serialization = "file://" . to_owned ( ) ;
24762522 let host_start = serialization. len ( ) as u32 ;
24772523 let ( host_end, host) = path_to_file_url_segments ( path. as_ref ( ) , & mut serialization) ?;
@@ -2506,9 +2552,14 @@ impl Url {
25062552 ///
25072553 /// Note that `std::path` does not consider trailing slashes significant
25082554 /// and usually does not include them (e.g. in `Path::parent()`).
2509- #[ cfg( any( unix, windows, target_os = "redox" , target_os = "wasi" ) ) ]
2555+ ///
2556+ /// This method is only available if the `std` Cargo feature is enabled.
2557+ #[ cfg( all(
2558+ feature = "std" ,
2559+ any( unix, windows, target_os = "redox" , target_os = "wasi" )
2560+ ) ) ]
25102561 #[ allow( clippy:: result_unit_err) ]
2511- pub fn from_directory_path < P : AsRef < Path > > ( path : P ) -> Result < Url , ( ) > {
2562+ pub fn from_directory_path < P : AsRef < std :: path :: Path > > ( path : P ) -> Result < Url , ( ) > {
25122563 let mut url = Url :: from_file_path ( path) ?;
25132564 if !url. serialization . ends_with ( '/' ) {
25142565 url. serialization . push ( '/' )
@@ -2622,8 +2673,13 @@ impl Url {
26222673 /// or if `Path::new_opt()` returns `None`.
26232674 /// (That is, if the percent-decoded path contains a NUL byte or,
26242675 /// for a Windows path, is not UTF-8.)
2676+ ///
2677+ /// This method is only available if the `std` Cargo feature is enabled.
26252678 #[ inline]
2626- #[ cfg( any( unix, windows, target_os = "redox" , target_os = "wasi" ) ) ]
2679+ #[ cfg( all(
2680+ feature = "std" ,
2681+ any( unix, windows, target_os = "redox" , target_os = "wasi" )
2682+ ) ) ]
26272683 #[ allow( clippy:: result_unit_err) ]
26282684 pub fn to_file_path ( & self ) -> Result < PathBuf , ( ) > {
26292685 if let Some ( segments) = self . path_segments ( ) {
@@ -2827,11 +2883,13 @@ impl<'de> serde::Deserialize<'de> for Url {
28272883 }
28282884}
28292885
2830- #[ cfg( any( unix, target_os = "redox" , target_os = "wasi" ) ) ]
2886+ #[ cfg( all ( feature = "std" , any( unix, target_os = "redox" , target_os = "wasi" ) ) ) ]
28312887fn path_to_file_url_segments (
28322888 path : & Path ,
28332889 serialization : & mut String ,
28342890) -> Result < ( u32 , HostInternal ) , ( ) > {
2891+ use parser:: SPECIAL_PATH_SEGMENT ;
2892+ use percent_encoding:: percent_encode;
28352893 #[ cfg( any( unix, target_os = "redox" ) ) ]
28362894 use std:: os:: unix:: prelude:: OsStrExt ;
28372895 #[ cfg( target_os = "wasi" ) ]
@@ -2857,7 +2915,7 @@ fn path_to_file_url_segments(
28572915 Ok ( ( host_end, HostInternal :: None ) )
28582916}
28592917
2860- #[ cfg( windows) ]
2918+ #[ cfg( all ( feature = "std" , windows) ) ]
28612919fn path_to_file_url_segments (
28622920 path : & Path ,
28632921 serialization : & mut String ,
@@ -2866,11 +2924,14 @@ fn path_to_file_url_segments(
28662924}
28672925
28682926// Build this unconditionally to alleviate https://github.com/servo/rust-url/issues/102
2927+ #[ cfg( feature = "std" ) ]
28692928#[ cfg_attr( not( windows) , allow( dead_code) ) ]
28702929fn path_to_file_url_segments_windows (
28712930 path : & Path ,
28722931 serialization : & mut String ,
28732932) -> Result < ( u32 , HostInternal ) , ( ) > {
2933+ use crate :: parser:: PATH_SEGMENT ;
2934+ use percent_encoding:: percent_encode;
28742935 use std:: path:: { Component , Prefix } ;
28752936 if !path. is_absolute ( ) {
28762937 return Err ( ( ) ) ;
@@ -2929,16 +2990,19 @@ fn path_to_file_url_segments_windows(
29292990 Ok ( ( host_end, host_internal) )
29302991}
29312992
2932- #[ cfg( any( unix, target_os = "redox" , target_os = "wasi" ) ) ]
2993+ #[ cfg( all ( feature = "std" , any( unix, target_os = "redox" , target_os = "wasi" ) ) ) ]
29332994fn file_url_segments_to_pathbuf (
29342995 host : Option < & str > ,
29352996 segments : str:: Split < ' _ , char > ,
29362997) -> Result < PathBuf , ( ) > {
2998+ use alloc:: vec:: Vec ;
2999+ use percent_encoding:: percent_decode;
29373000 use std:: ffi:: OsStr ;
29383001 #[ cfg( any( unix, target_os = "redox" ) ) ]
29393002 use std:: os:: unix:: prelude:: OsStrExt ;
29403003 #[ cfg( target_os = "wasi" ) ]
29413004 use std:: os:: wasi:: prelude:: OsStrExt ;
3005+ use std:: path:: PathBuf ;
29423006
29433007 if host. is_some ( ) {
29443008 return Err ( ( ) ) ;
@@ -2974,7 +3038,7 @@ fn file_url_segments_to_pathbuf(
29743038 Ok ( path)
29753039}
29763040
2977- #[ cfg( windows) ]
3041+ #[ cfg( all ( feature = "std" , windows) ) ]
29783042fn file_url_segments_to_pathbuf (
29793043 host : Option < & str > ,
29803044 segments : str:: Split < char > ,
@@ -2983,11 +3047,13 @@ fn file_url_segments_to_pathbuf(
29833047}
29843048
29853049// Build this unconditionally to alleviate https://github.com/servo/rust-url/issues/102
3050+ #[ cfg( feature = "std" ) ]
29863051#[ cfg_attr( not( windows) , allow( dead_code) ) ]
29873052fn file_url_segments_to_pathbuf_windows (
29883053 host : Option < & str > ,
29893054 mut segments : str:: Split < ' _ , char > ,
29903055) -> Result < PathBuf , ( ) > {
3056+ use percent_encoding:: percent_decode;
29913057 let mut string = if let Some ( host) = host {
29923058 r"\\" . to_owned ( ) + host
29933059 } else {
0 commit comments