Skip to content

no_std support for all crates #717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ jobs:
with:
command: test
args: --all-features
- uses: actions-rs/cargo@v1
# --no-default-features only available since 1.51.0
if: matrix.rust != '1.45.0'
with:
command: test
args: --no-default-features

WASM:
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions data-url/src/forgiving_base64.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! <https://infra.spec.whatwg.org/#forgiving-base64-decode>

use alloc::vec::Vec;

#[derive(Debug)]
pub struct InvalidBase64(InvalidBase64Details);

Expand Down
6 changes: 6 additions & 0 deletions data-url/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
//! assert_eq!(body, b"Hello World!");
//! assert!(fragment.is_none());
//! ```
#![no_std]

#[macro_use]
extern crate alloc;

use alloc::{string::String, vec::Vec};

macro_rules! require {
($condition: expr) => {
Expand Down
5 changes: 3 additions & 2 deletions data-url/src/mime.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::fmt::{self, Write};
use std::str::FromStr;
use alloc::{borrow::ToOwned, string::String, vec::Vec};
use core::fmt::{self, Write};
use core::str::FromStr;

/// <https://mimesniff.spec.whatwg.org/#mime-type-representation>
#[derive(Debug, PartialEq, Eq)]
Expand Down
8 changes: 6 additions & 2 deletions form_urlencoded/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@
//!
//! Converts between a string (such as an URL’s query string)
//! and a sequence of (name, value) pairs.
#![no_std]

extern crate alloc;

use alloc::borrow::{Borrow, Cow, ToOwned};
use alloc::string::String;
use core::str;
use percent_encoding::{percent_decode, percent_encode_byte};
use std::borrow::{Borrow, Cow};
use std::str;

/// Convert a byte string in the `application/x-www-form-urlencoded` syntax
/// into a iterator of (name, value) pairs.
Expand Down
8 changes: 6 additions & 2 deletions idna/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ rust-version = "1.45"
[lib]
doctest = false

[features]
default = ["std"]
std = []

[[test]]
name = "tests"
harness = false
Expand All @@ -26,8 +30,8 @@ tester = "0.9"
serde_json = "1.0"

[dependencies]
unicode-bidi = "0.3"
unicode-normalization = "0.1.17"
unicode-bidi = { version = "0.3.7", default-features = false }
unicode-normalization = { version = "0.1.17", default-features = false }

[[bench]]
name = "all"
Expand Down
8 changes: 8 additions & 0 deletions idna/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,19 @@
//! > This document specifies a mechanism
//! > that minimizes the impact of this transition for client software,
//! > allowing client software to access domains that are valid under either system.
#![no_std]

extern crate alloc;

#[cfg(feature = "std")]
extern crate std;

#[cfg(test)]
#[macro_use]
extern crate assert_matches;

use alloc::string::String;

pub mod punycode;
mod uts46;

Expand Down
7 changes: 4 additions & 3 deletions idna/src/punycode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
//! `encode_str` and `decode_to_string` provide convenience wrappers
//! that convert from and to Rust’s UTF-8 based `str` and `String` types.

use std::char;
use std::u32;
use alloc::{string::String, vec::Vec};
use core::char;
use core::u32;

// Bootstring parameters for Punycode
static BASE: u32 = 36;
Expand Down Expand Up @@ -168,7 +169,7 @@ impl Decoder {
}

pub(crate) struct Decode<'a> {
base: std::str::Chars<'a>,
base: core::str::Chars<'a>,
pub(crate) insertions: &'a [(usize, char)],
inserted: usize,
position: usize,
Expand Down
11 changes: 7 additions & 4 deletions idna/src/uts46.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@

use self::Mapping::*;
use crate::punycode;
use std::{error::Error as StdError, fmt};

use alloc::string::String;
use core::fmt;
use unicode_bidi::{bidi_class, BidiClass};
use unicode_normalization::char::is_combining_mark;
use unicode_normalization::{is_nfc, UnicodeNormalization};
Expand Down Expand Up @@ -70,10 +72,10 @@ fn find_char(codepoint: char) -> &'static Mapping {
}

struct Mapper<'a> {
chars: std::str::Chars<'a>,
chars: core::str::Chars<'a>,
config: Config,
errors: &'a mut Errors,
slice: Option<std::str::Chars<'static>>,
slice: Option<core::str::Chars<'static>>,
}

impl<'a> Iterator for Mapper<'a> {
Expand Down Expand Up @@ -697,7 +699,8 @@ impl From<Errors> for Result<(), Errors> {
}
}

impl StdError for Errors {}
#[cfg(feature = "std")]
impl std::error::Error for Errors {}

impl fmt::Display for Errors {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down
7 changes: 4 additions & 3 deletions url/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ bencher = "0.1"

[dependencies]
form_urlencoded = { version = "1.0.0", path = "../form_urlencoded" }
idna = { version = "0.2.0", path = "../idna", optional = true }
idna = { version = "0.2.0", default-features = false, path = "../idna", optional = true }
percent-encoding = { version = "2.1.0", path = "../percent_encoding" }
serde = {version = "1.0", optional = true, features = ["derive"]}
serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] }

[features]
default = ["idna"]
default = ["std", "idna"]
std = ["idna/std"]

[[bench]]
name = "parse_url"
Expand Down
7 changes: 5 additions & 2 deletions url/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::cmp;
use std::fmt::{self, Formatter};
use alloc::borrow::ToOwned;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use core::cmp;
use core::fmt::{self, Formatter};
use std::net::{Ipv4Addr, Ipv6Addr};

use percent_encoding::{percent_decode, utf8_percent_encode, CONTROLS};
Expand Down
70 changes: 48 additions & 22 deletions url/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,27 +131,36 @@ url = { version = "2", default-features = false }
*/

#![doc(html_root_url = "https://docs.rs/url/2.2.2")]
#![no_std]
#[macro_use]
extern crate alloc;
extern crate std;

pub use form_urlencoded;

#[cfg(feature = "serde")]
extern crate serde;

use crate::host::HostInternal;
use crate::parser::{to_u32, Context, Parser, SchemeType, 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 std::io;
use std::mem;
use std::net::{IpAddr, SocketAddr, ToSocketAddrs};
use std::ops::{Range, RangeFrom, RangeTo};
use std::path::{Path, PathBuf};
use std::str;

use std::convert::TryFrom;
use crate::parser::{to_u32, Context, Parser, SchemeType, USERINFO};
use alloc::borrow::ToOwned;
use alloc::string::{String, ToString};
use core::borrow::Borrow;
use core::cmp;
use core::convert::TryFrom;
use core::fmt::{self, Write};
use core::hash;
use core::mem;
use core::ops::{Range, RangeFrom, RangeTo};
use core::str;
use percent_encoding::utf8_percent_encode;
use std::net::IpAddr;
#[cfg(feature = "std")]
use std::{
io,
net::{SocketAddr, ToSocketAddrs},
path::{Path, PathBuf},
};

pub use crate::host::Host;
pub use crate::origin::{OpaqueOrigin, Origin};
Expand Down Expand Up @@ -1144,10 +1153,11 @@ impl Url {
/// })
/// }
/// ```
#[cfg(feature = "std")]
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`:
//
Expand All @@ -1156,6 +1166,7 @@ impl Url {
// > This RFC proposes that *all* type parameters are considered in scope
// > for `impl Trait` in return position

// TODO: Return custom error type to support no_std
fn io_result<T>(opt: Option<T>, message: &str) -> io::Result<T> {
opt.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, message))
}
Expand Down Expand Up @@ -2314,7 +2325,9 @@ 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, ()> {
let mut serialization = "file://".to_owned();
Expand Down Expand Up @@ -2351,7 +2364,9 @@ 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, ()> {
let mut url = Url::from_file_path(path)?;
Expand Down Expand Up @@ -2467,8 +2482,10 @@ 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() {
Expand Down Expand Up @@ -2672,11 +2689,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 crate::parser::PATH_SEGMENT;
use percent_encoding::percent_encode;
#[cfg(any(unix, target_os = "redox"))]
use std::os::unix::prelude::OsStrExt;
#[cfg(target_os = "wasi")]
Expand All @@ -2702,20 +2721,23 @@ 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,
) -> Result<(u32, HostInternal), ()> {
path_to_file_url_segments_windows(path, serialization)
}

#[cfg(feature = "std")]
// Build this unconditionally to alleviate https://github.com/servo/rust-url/issues/102
#[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(());
Expand Down Expand Up @@ -2770,11 +2792,13 @@ 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;
Expand Down Expand Up @@ -2810,20 +2834,22 @@ 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>,
) -> Result<PathBuf, ()> {
file_url_segments_to_pathbuf_windows(host, segments)
}

#[cfg(feature = "std")]
// Build this unconditionally to alleviate https://github.com/servo/rust-url/issues/102
#[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 {
Expand Down
5 changes: 4 additions & 1 deletion url/src/origin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
use crate::host::Host;
use crate::parser::default_port;
use crate::Url;
use std::sync::atomic::{AtomicUsize, Ordering};
use alloc::borrow::ToOwned;
use alloc::string::String;
use core::sync::atomic::{AtomicUsize, Ordering};
use idna::domain_to_unicode;

pub fn url_origin(url: &Url) -> Origin {
let scheme = url.scheme();
Expand Down
Loading