Skip to content

Commit 43c7d41

Browse files
committed
no_std support for url
1 parent 54346fa commit 43c7d41

File tree

8 files changed

+78
-44
lines changed

8 files changed

+78
-44
lines changed

url/Cargo.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ documentation = "https://docs.rs/url"
1010
repository = "https://github.com/servo/rust-url"
1111
readme = "../README.md"
1212
keywords = ["url", "parser"]
13-
categories = ["parser-implementations", "web-programming", "encoding"]
13+
categories = ["parser-implementations", "web-programming", "encoding", "no_std"]
1414
license = "MIT OR Apache-2.0"
1515
include = ["src/**/*", "LICENSE-*", "README.md", "tests/**"]
1616
edition = "2018"
@@ -25,13 +25,15 @@ bencher = "0.1"
2525
wasm-bindgen-test = "0.3"
2626

2727
[dependencies]
28-
form_urlencoded = { version = "1.2.1", path = "../form_urlencoded" }
29-
idna = { version = "0.5.0", path = "../idna" }
30-
percent-encoding = { version = "2.3.1", path = "../percent_encoding" }
28+
form_urlencoded = { version = "1.2.1", path = "../form_urlencoded", default-features = false }
29+
idna = { version = "0.5.0", path = "../idna", default-features = false }
30+
percent-encoding = { version = "2.3.1", path = "../percent_encoding", default-features = false }
3131
serde = { version = "1.0", optional = true, features = ["derive"] }
3232

3333
[features]
34-
default = []
34+
default = ["std"]
35+
std = ["alloc", "form_urlencoded/std", "idna/std", "percent-encoding/std"]
36+
alloc = ["form_urlencoded/alloc", "idna/alloc", "percent-encoding/alloc"]
3537
# Enable to use the #[debugger_visualizer] attribute. This feature requires Rust >= 1.71.
3638
debugger_visualizer = []
3739
# Expose internal offsets of the URL.

url/src/host.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9-
use std::cmp;
10-
use std::fmt::{self, Formatter};
11-
use std::net::{Ipv4Addr, Ipv6Addr};
9+
use core::cmp;
10+
use core::fmt::{self, Formatter};
11+
use std_core_compat::net::{Ipv4Addr, Ipv6Addr};
12+
use alloc::borrow::ToOwned;
13+
use alloc::string::String;
14+
use alloc::string::ToString;
15+
use alloc::vec::Vec;
1216

1317
use percent_encoding::{percent_decode, utf8_percent_encode, CONTROLS};
1418
#[cfg(feature = "serde")]

url/src/lib.rs

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,21 @@ url = { version = "2", features = ["debugger_visualizer"] }
139139
feature = "debugger_visualizer",
140140
debugger_visualizer(natvis_file = "../../debug_metadata/url.natvis")
141141
)]
142+
#![cfg_attr(not(feature = "std"), no_std)]
143+
144+
// Use std_core_compat for dependencies that
145+
// are in std in the Minimum Supported Rust Version
146+
// and in core in the latest stable release.
147+
#[cfg(feature = "std")]
148+
extern crate std as std_core_compat;
149+
150+
#[cfg(not(feature = "std"))]
151+
extern crate core as std_core_compat;
152+
153+
extern crate alloc;
154+
155+
#[cfg(not(feature = "alloc"))]
156+
compile_error!("the `alloc` feature must currently be enabled");
142157

143158
pub use form_urlencoded;
144159

@@ -150,21 +165,21 @@ use crate::parser::{
150165
to_u32, Context, Parser, SchemeType, PATH_SEGMENT, SPECIAL_PATH_SEGMENT, USERINFO,
151166
};
152167
use percent_encoding::{percent_decode, percent_encode, utf8_percent_encode};
153-
use std::borrow::Borrow;
154-
use std::cmp;
155-
use std::fmt::{self, Write};
156-
use std::hash;
157-
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
158-
use std::io;
159-
use std::mem;
160-
use std::net::IpAddr;
161-
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
162-
use std::net::{SocketAddr, ToSocketAddrs};
163-
use std::ops::{Range, RangeFrom, RangeTo};
164-
use std::path::{Path, PathBuf};
165-
use std::str;
166-
167-
use std::convert::TryFrom;
168+
use core::borrow::Borrow;
169+
use core::cmp;
170+
use core::fmt::{self, Write};
171+
use core::hash;
172+
use core::mem;
173+
use std_core_compat::net::IpAddr;
174+
use core::ops::{Range, RangeFrom, RangeTo};
175+
use core::str;
176+
177+
use alloc::borrow::ToOwned;
178+
use alloc::format;
179+
use alloc::string::String;
180+
use alloc::string::ToString;
181+
182+
use core::convert::TryFrom;
168183

169184
pub use crate::host::Host;
170185
pub use crate::origin::{OpaqueOrigin, Origin};
@@ -1276,11 +1291,13 @@ impl Url {
12761291
/// })
12771292
/// }
12781293
/// ```
1279-
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
1294+
#[cfg(all(feature = "std", any(unix, windows, target_os = "redox", target_os = "wasi")))]
12801295
pub fn socket_addrs(
12811296
&self,
12821297
default_port_number: impl Fn() -> Option<u16>,
1283-
) -> io::Result<Vec<SocketAddr>> {
1298+
) -> std::io::Result<Vec<std::net::SocketAddr>> {
1299+
use std::net::ToSocketAddrs;
1300+
use std::io;
12841301
// Note: trying to avoid the Vec allocation by returning `impl AsRef<[SocketAddr]>`
12851302
// causes borrowck issues because the return value borrows `default_port_number`:
12861303
//
@@ -2466,9 +2483,9 @@ impl Url {
24662483
/// # run().unwrap();
24672484
/// # }
24682485
/// ```
2469-
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
2486+
#[cfg(all(feature = "std", any(unix, windows, target_os = "redox", target_os = "wasi")))]
24702487
#[allow(clippy::result_unit_err)]
2471-
pub fn from_file_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> {
2488+
pub fn from_file_path<P: AsRef<std::path::Path>>(path: P) -> Result<Url, ()> {
24722489
let mut serialization = "file://".to_owned();
24732490
let host_start = serialization.len() as u32;
24742491
let (host_end, host) = path_to_file_url_segments(path.as_ref(), &mut serialization)?;
@@ -2503,9 +2520,9 @@ impl Url {
25032520
///
25042521
/// Note that `std::path` does not consider trailing slashes significant
25052522
/// and usually does not include them (e.g. in `Path::parent()`).
2506-
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
2523+
#[cfg(all(feature = "std", any(unix, windows, target_os = "redox", target_os = "wasi")))]
25072524
#[allow(clippy::result_unit_err)]
2508-
pub fn from_directory_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> {
2525+
pub fn from_directory_path<P: AsRef<std::path::Path>>(path: P) -> Result<Url, ()> {
25092526
let mut url = Url::from_file_path(path)?;
25102527
if !url.serialization.ends_with('/') {
25112528
url.serialization.push('/')
@@ -2620,9 +2637,9 @@ impl Url {
26202637
/// (That is, if the percent-decoded path contains a NUL byte or,
26212638
/// for a Windows path, is not UTF-8.)
26222639
#[inline]
2623-
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
2640+
#[cfg(all(feature = "std", any(unix, windows, target_os = "redox", target_os = "wasi")))]
26242641
#[allow(clippy::result_unit_err)]
2625-
pub fn to_file_path(&self) -> Result<PathBuf, ()> {
2642+
pub fn to_file_path(&self) -> Result<std::path::PathBuf, ()> {
26262643
if let Some(segments) = self.path_segments() {
26272644
let host = match self.host() {
26282645
None | Some(Host::Domain("localhost")) => None,
@@ -2824,9 +2841,9 @@ impl<'de> serde::Deserialize<'de> for Url {
28242841
}
28252842
}
28262843

2827-
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))]
2844+
#[cfg(all(feature = "std", any(unix, target_os = "redox", target_os = "wasi")))]
28282845
fn path_to_file_url_segments(
2829-
path: &Path,
2846+
path: &std::path::Path,
28302847
serialization: &mut String,
28312848
) -> Result<(u32, HostInternal), ()> {
28322849
#[cfg(any(unix, target_os = "redox"))]
@@ -2864,8 +2881,9 @@ fn path_to_file_url_segments(
28642881

28652882
// Build this unconditionally to alleviate https://github.com/servo/rust-url/issues/102
28662883
#[cfg_attr(not(windows), allow(dead_code))]
2884+
#[cfg(feature = "std")]
28672885
fn path_to_file_url_segments_windows(
2868-
path: &Path,
2886+
path: &std::path::Path,
28692887
serialization: &mut String,
28702888
) -> Result<(u32, HostInternal), ()> {
28712889
use std::path::{Component, Prefix};
@@ -2926,12 +2944,13 @@ fn path_to_file_url_segments_windows(
29262944
Ok((host_end, host_internal))
29272945
}
29282946

2929-
#[cfg(any(unix, target_os = "redox", target_os = "wasi"))]
2947+
#[cfg(all(feature = "std", any(unix, target_os = "redox", target_os = "wasi")))]
29302948
fn file_url_segments_to_pathbuf(
29312949
host: Option<&str>,
29322950
segments: str::Split<'_, char>,
2933-
) -> Result<PathBuf, ()> {
2951+
) -> Result<std::path::PathBuf, ()> {
29342952
use std::ffi::OsStr;
2953+
use std::path::PathBuf;
29352954
#[cfg(any(unix, target_os = "redox"))]
29362955
use std::os::unix::prelude::OsStrExt;
29372956
#[cfg(target_os = "wasi")]
@@ -2981,10 +3000,11 @@ fn file_url_segments_to_pathbuf(
29813000

29823001
// Build this unconditionally to alleviate https://github.com/servo/rust-url/issues/102
29833002
#[cfg_attr(not(windows), allow(dead_code))]
3003+
#[cfg(feature = "std")]
29843004
fn file_url_segments_to_pathbuf_windows(
29853005
host: Option<&str>,
29863006
mut segments: str::Split<'_, char>,
2987-
) -> Result<PathBuf, ()> {
3007+
) -> Result<std::path::PathBuf, ()> {
29883008
let mut string = if let Some(host) = host {
29893009
r"\\".to_owned() + host
29903010
} else {
@@ -3024,7 +3044,7 @@ fn file_url_segments_to_pathbuf_windows(
30243044
Err(..) => return Err(()),
30253045
}
30263046
}
3027-
let path = PathBuf::from(string);
3047+
let path = std::path::PathBuf::from(string);
30283048
debug_assert!(
30293049
path.is_absolute(),
30303050
"to_file_path() failed to produce an absolute Path"

url/src/origin.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
use crate::host::Host;
1010
use crate::parser::default_port;
1111
use crate::Url;
12-
use std::sync::atomic::{AtomicUsize, Ordering};
12+
use core::sync::atomic::{AtomicUsize, Ordering};
13+
use alloc::borrow::ToOwned;
14+
use alloc::format;
15+
use alloc::string::String;
1316

1417
pub fn url_origin(url: &Url) -> Origin {
1518
let scheme = url.scheme();

url/src/parser.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9-
use std::error::Error;
10-
use std::fmt::{self, Formatter, Write};
11-
use std::str;
9+
use std_core_compat::error::Error;
10+
use core::fmt::{self, Formatter, Write};
11+
use core::str;
12+
use alloc::string::String;
13+
use alloc::string::ToString;
1214

1315
use crate::host::{Host, HostInternal};
1416
use crate::Url;

url/src/path_segments.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
use crate::parser::{self, to_u32, SchemeType};
1010
use crate::Url;
11-
use std::str;
11+
use core::str;
12+
use alloc::string::String;
1213

1314
/// Exposes methods to manipulate the path of an URL that is not cannot-be-base.
1415
///

url/src/quirks.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
1414
use crate::parser::{default_port, Context, Input, Parser, SchemeType};
1515
use crate::{Host, ParseError, Position, Url};
16+
use alloc::string::String;
17+
use alloc::string::ToString;
1618

1719
/// Internal components / offsets of a URL.
1820
///

url/src/slicing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// except according to those terms.
88

99
use crate::Url;
10-
use std::ops::{Index, Range, RangeFrom, RangeFull, RangeTo};
10+
use core::ops::{Index, Range, RangeFrom, RangeFull, RangeTo};
1111

1212
impl Index<RangeFull> for Url {
1313
type Output = str;

0 commit comments

Comments
 (0)