|
|
@@ -73,6 +73,14 @@ assert!(data_url.fragment() == Some(""));
|
|
|
# run().unwrap();
|
|
|
```
|
|
|
|
|
|
+## Default Features
|
|
|
+
|
|
|
+Versions `<= 2.5.2` of the crate have no default features. Versions `> 2.5.2` have the default feature 'std'.
|
|
|
+If you are upgrading across this boundary and you have specified `default-features = false`, then
|
|
|
+you will need to add the 'std' feature or the 'alloc' feature to your dependency.
|
|
|
+The 'std' feature has the same behavior as the previous versions. The 'alloc' feature
|
|
|
+provides no_std support.
|
|
|
+
|
|
|
## Serde
|
|
|
|
|
|
Enable the `serde` feature to include `Deserialize` and `Serialize` implementations for `url::Url`.
|
|
|
@@ -134,6 +142,7 @@ url = { version = "2", features = ["debugger_visualizer"] }
|
|
|
|
|
|
*/
|
|
|
|
|
|
+#![no_std]
|
|
|
#![doc(html_root_url = "https://docs.rs/url/2.5.2")]
|
|
|
#![cfg_attr(
|
|
|
feature = "debugger_visualizer",
|
|
|
@@ -145,29 +154,48 @@ url = { version = "2", features = ["debugger_visualizer"] }
|
|
|
|
|
|
pub use form_urlencoded;
|
|
|
|
|
|
+// For forwards compatibility
|
|
|
+#[cfg(feature = "std")]
|
|
|
+extern crate std;
|
|
|
+
|
|
|
+#[macro_use]
|
|
|
+extern crate alloc;
|
|
|
+
|
|
|
#[cfg(feature = "serde")]
|
|
|
extern crate serde;
|
|
|
|
|
|
use crate::host::HostInternal;
|
|
|
-use crate::parser::{
|
|
|
- to_u32, Context, Parser, SchemeType, PATH_SEGMENT, SPECIAL_PATH_SEGMENT, USERINFO,
|
|
|
-};
|
|
|
-use percent_encoding::{percent_decode, percent_encode, utf8_percent_encode};
|
|
|
-use std::borrow::Borrow;
|
|
|
-use std::cmp;
|
|
|
-use std::fmt::{self, Write};
|
|
|
-use std::hash;
|
|
|
+
|
|
|
+use crate::net::IpAddr;
|
|
|
+#[cfg(feature = "std")]
|
|
|
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
|
|
|
-use std::io;
|
|
|
-use std::mem;
|
|
|
-use std::net::IpAddr;
|
|
|
+use crate::net::{SocketAddr, ToSocketAddrs};
|
|
|
+use crate::parser::{to_u32, Context, Parser, SchemeType, USERINFO};
|
|
|
+use alloc::borrow::ToOwned;
|
|
|
+use alloc::str;
|
|
|
+use alloc::string::{String, ToString};
|
|
|
+use core::borrow::Borrow;
|
|
|
+use core::convert::TryFrom;
|
|
|
+use core::fmt::Write;
|
|
|
+use core::ops::{Range, RangeFrom, RangeTo};
|
|
|
+use core::{cmp, fmt, hash, mem};
|
|
|
+use percent_encoding::utf8_percent_encode;
|
|
|
+#[cfg(feature = "std")]
|
|
|
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
|
|
|
-use std::net::{SocketAddr, ToSocketAddrs};
|
|
|
-use std::ops::{Range, RangeFrom, RangeTo};
|
|
|
+use std::io;
|
|
|
+#[cfg(feature = "std")]
|
|
|
use std::path::{Path, PathBuf};
|
|
|
-use std::str;
|
|
|
|
|
|
-use std::convert::TryFrom;
|
|
|
+/// `std` version of `net`
|
|
|
+#[cfg(feature = "std")]
|
|
|
+pub(crate) mod net {
|
|
|
+ pub use std::net::*;
|
|
|
+}
|
|
|
+/// `no_std` nightly version of `net`
|
|
|
+#[cfg(not(feature = "std"))]
|
|
|
+pub(crate) mod net {
|
|
|
+ pub use core::net::*;
|
|
|
+}
|
|
|
|
|
|
pub use crate::host::Host;
|
|
|
pub use crate::origin::{OpaqueOrigin, Origin};
|
|
|
@@ -1279,11 +1307,12 @@ impl Url {
|
|
|
/// })
|
|
|
/// }
|
|
|
/// ```
|
|
|
+ #[cfg(feature = "std")]
|
|
|
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
|
|
|
pub fn socket_addrs(
|
|
|
&self,
|
|
|
default_port_number: impl Fn() -> Option<u16>,
|
|
|
- ) -> io::Result<Vec<SocketAddr>> {
|
|
|
+ ) -> io::Result<alloc::vec::Vec<SocketAddr>> {
|
|
|
// Note: trying to avoid the Vec allocation by returning `impl AsRef<[SocketAddr]>`
|
|
|
// causes borrowck issues because the return value borrows `default_port_number`:
|
|
|
//
|
|
|
@@ -1353,7 +1382,11 @@ impl Url {
|
|
|
///
|
|
|
/// ```
|
|
|
/// use url::Url;
|
|
|
+ ///
|
|
|
+ /// # #[cfg(feature = "std")]
|
|
|
/// # use std::error::Error;
|
|
|
+ /// # #[cfg(not(feature = "std"))]
|
|
|
+ /// # use core::error::Error;
|
|
|
///
|
|
|
/// # fn run() -> Result<(), Box<dyn Error>> {
|
|
|
/// let url = Url::parse("https://example.com/foo/bar")?;
|
|
|
@@ -1767,7 +1800,11 @@ impl Url {
|
|
|
///
|
|
|
/// ```
|
|
|
/// use url::Url;
|
|
|
+ ///
|
|
|
+ /// # #[cfg(feature = "std")]
|
|
|
/// # use std::error::Error;
|
|
|
+ /// # #[cfg(not(feature = "std"))]
|
|
|
+ /// # use core::error::Error;
|
|
|
///
|
|
|
/// # fn run() -> Result<(), Box<dyn Error>> {
|
|
|
/// let mut url = Url::parse("ssh://example.net:2048/")?;
|
|
|
@@ -1786,7 +1823,11 @@ impl Url {
|
|
|
///
|
|
|
/// ```rust
|
|
|
/// use url::Url;
|
|
|
+ ///
|
|
|
+ /// # #[cfg(feature = "std")]
|
|
|
/// # use std::error::Error;
|
|
|
+ /// # #[cfg(not(feature = "std"))]
|
|
|
+ /// # use core::error::Error;
|
|
|
///
|
|
|
/// # fn run() -> Result<(), Box<dyn Error>> {
|
|
|
/// let mut url = Url::parse("https://example.org/")?;
|
|
|
@@ -2469,9 +2510,14 @@ impl Url {
|
|
|
/// # run().unwrap();
|
|
|
/// # }
|
|
|
/// ```
|
|
|
- #[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
|
|
|
+ ///
|
|
|
+ /// This method is only available if the `std` Cargo feature is enabled.
|
|
|
+ #[cfg(all(
|
|
|
+ feature = "std",
|
|
|
+ any(unix, windows, target_os = "redox", target_os = "wasi")
|
|
|
+ ))]
|
|
|
#[allow(clippy::result_unit_err)]
|
|
|
- pub fn from_file_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> {
|
|
|
+ pub fn from_file_path<P: AsRef<std::path::Path>>(path: P) -> Result<Url, ()> {
|
|
|
let mut serialization = "file://".to_owned();
|
|
|
let host_start = serialization.len() as u32;
|
|
|
let (host_end, host) = path_to_file_url_segments(path.as_ref(), &mut serialization)?;
|
|
|
@@ -2506,9 +2552,14 @@ impl Url {
|
|
|
///
|
|
|
/// Note that `std::path` does not consider trailing slashes significant
|
|
|
/// and usually does not include them (e.g. in `Path::parent()`).
|
|
|
- #[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
|
|
|
+ ///
|
|
|
+ /// This method is only available if the `std` Cargo feature is enabled.
|
|
|
+ #[cfg(all(
|
|
|
+ feature = "std",
|
|
|
+ any(unix, windows, target_os = "redox", target_os = "wasi")
|
|
|
+ ))]
|
|
|
#[allow(clippy::result_unit_err)]
|
|
|
- pub fn from_directory_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> {
|
|
|
+ pub fn from_directory_path<P: AsRef<std::path::Path>>(path: P) -> Result<Url, ()> {
|
|
|
let mut url = Url::from_file_path(path)?;
|
|
|
if !url.serialization.ends_with('/') {
|
|
|
url.serialization.push('/')
|
|
|
@@ -2622,8 +2673,13 @@ impl Url {
|
|
|
/// or if `Path::new_opt()` returns `None`.
|
|
|
/// (That is, if the percent-decoded path contains a NUL byte or,
|
|
|
/// for a Windows path, is not UTF-8.)
|
|
|
+ ///
|
|
|
+ /// This method is only available if the `std` Cargo feature is enabled.
|
|
|
#[inline]
|
|
|
- #[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
|
|
|
+ #[cfg(all(
|
|
|
+ feature = "std",
|
|
|
+ any(unix, windows, target_os = "redox", target_os = "wasi")
|
|
|
+ ))]
|
|
|
#[allow(clippy::result_unit_err)]
|
|
|
pub fn to_file_path(&self) -> Result<PathBuf, ()> {
|
|
|
if let Some(segments) = self.path_segments() {
|
|
|
@@ -2827,11 +2883,13 @@ impl<'de> serde::Deserialize<'de> for Url {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#[cfg(any(unix, target_os = "redox", target_os = "wasi"))]
|
|
|
+#[cfg(all(feature = "std", any(unix, target_os = "redox", target_os = "wasi")))]
|
|
|
fn path_to_file_url_segments(
|
|
|
path: &Path,
|
|
|
serialization: &mut String,
|
|
|
) -> Result<(u32, HostInternal), ()> {
|
|
|
+ use parser::SPECIAL_PATH_SEGMENT;
|
|
|
+ use percent_encoding::percent_encode;
|
|
|
#[cfg(any(unix, target_os = "redox"))]
|
|
|
use std::os::unix::prelude::OsStrExt;
|
|
|
#[cfg(target_os = "wasi")]
|
|
|
@@ -2857,7 +2915,7 @@ fn path_to_file_url_segments(
|
|
|
Ok((host_end, HostInternal::None))
|
|
|
}
|
|
|
|
|
|
-#[cfg(windows)]
|
|
|
+#[cfg(all(feature = "std", windows))]
|
|
|
fn path_to_file_url_segments(
|
|
|
path: &Path,
|
|
|
serialization: &mut String,
|
|
|
@@ -2866,11 +2924,14 @@ fn path_to_file_url_segments(
|
|
|
}
|
|
|
|
|
|
// Build this unconditionally to alleviate https://github.com/servo/rust-url/issues/102
|
|
|
+#[cfg(feature = "std")]
|
|
|
#[cfg_attr(not(windows), allow(dead_code))]
|
|
|
fn path_to_file_url_segments_windows(
|
|
|
path: &Path,
|
|
|
serialization: &mut String,
|
|
|
) -> Result<(u32, HostInternal), ()> {
|
|
|
+ use crate::parser::PATH_SEGMENT;
|
|
|
+ use percent_encoding::percent_encode;
|
|
|
use std::path::{Component, Prefix};
|
|
|
if !path.is_absolute() {
|
|
|
return Err(());
|
|
|
@@ -2929,16 +2990,19 @@ fn path_to_file_url_segments_windows(
|
|
|
Ok((host_end, host_internal))
|
|
|
}
|
|
|
|
|
|
-#[cfg(any(unix, target_os = "redox", target_os = "wasi"))]
|
|
|
+#[cfg(all(feature = "std", any(unix, target_os = "redox", target_os = "wasi")))]
|
|
|
fn file_url_segments_to_pathbuf(
|
|
|
host: Option<&str>,
|
|
|
segments: str::Split<'_, char>,
|
|
|
) -> Result<PathBuf, ()> {
|
|
|
+ use alloc::vec::Vec;
|
|
|
+ use percent_encoding::percent_decode;
|
|
|
use std::ffi::OsStr;
|
|
|
#[cfg(any(unix, target_os = "redox"))]
|
|
|
use std::os::unix::prelude::OsStrExt;
|
|
|
#[cfg(target_os = "wasi")]
|
|
|
use std::os::wasi::prelude::OsStrExt;
|
|
|
+ use std::path::PathBuf;
|
|
|
|
|
|
if host.is_some() {
|
|
|
return Err(());
|
|
|
@@ -2974,7 +3038,7 @@ fn file_url_segments_to_pathbuf(
|
|
|
Ok(path)
|
|
|
}
|
|
|
|
|
|
-#[cfg(windows)]
|
|
|
+#[cfg(all(feature = "std", windows))]
|
|
|
fn file_url_segments_to_pathbuf(
|
|
|
host: Option<&str>,
|
|
|
segments: str::Split<char>,
|
|
|
@@ -2983,11 +3047,13 @@ fn file_url_segments_to_pathbuf(
|
|
|
}
|
|
|
|
|
|
// Build this unconditionally to alleviate https://github.com/servo/rust-url/issues/102
|
|
|
+#[cfg(feature = "std")]
|
|
|
#[cfg_attr(not(windows), allow(dead_code))]
|
|
|
fn file_url_segments_to_pathbuf_windows(
|
|
|
host: Option<&str>,
|
|
|
mut segments: str::Split<'_, char>,
|
|
|
) -> Result<PathBuf, ()> {
|
|
|
+ use percent_encoding::percent_decode;
|
|
|
let mut string = if let Some(host) = host {
|
|
|
r"\\".to_owned() + host
|
|
|
} else {
|