diff --git a/Cargo.toml b/Cargo.toml index 487507f0..7ae29358 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ std = [] [dependencies] bytes = "1" fnv = "1.0.5" +hashbrown = "0.12.0" itoa = "1" [dev-dependencies] diff --git a/benches/src/header_map/basic.rs b/benches/src/header_map/basic.rs index 8c198a02..ccd8ee9f 100644 --- a/benches/src/header_map/basic.rs +++ b/benches/src/header_map/basic.rs @@ -6,7 +6,7 @@ macro_rules! bench { use fnv::FnvHasher; use http::header::*; use seahash::SeaHasher; - use std::hash::BuildHasherDefault; + #[allow(unused_imports)] use test::{self, Bencher}; diff --git a/src/byte_str.rs b/src/byte_str.rs index 90872ecb..f1c50ba3 100644 --- a/src/byte_str.rs +++ b/src/byte_str.rs @@ -1,6 +1,7 @@ -use bytes::Bytes; +use core::ops; -use std::{ops, str}; +use alloc::string::String; +use bytes::Bytes; #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub(crate) struct ByteStr { @@ -34,7 +35,7 @@ impl ByteStr { /// behavior to call this with `bytes` that is not valid UTF-8. pub unsafe fn from_utf8_unchecked(bytes: Bytes) -> ByteStr { if cfg!(debug_assertions) { - match str::from_utf8(&bytes) { + match core::str::from_utf8(&bytes) { Ok(_) => (), Err(err) => panic!( "ByteStr::from_utf8_unchecked() with invalid bytes; error = {}, bytes = {:?}", @@ -54,7 +55,7 @@ impl ops::Deref for ByteStr { fn deref(&self) -> &str { let b: &[u8] = self.bytes.as_ref(); // Safety: the invariant of `bytes` is that it contains valid UTF-8. - unsafe { str::from_utf8_unchecked(b) } + unsafe { core::str::from_utf8_unchecked(b) } } } diff --git a/src/convert.rs b/src/convert.rs index 682e0ed5..633c0568 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -1,11 +1,11 @@ macro_rules! if_downcast_into { ($in_ty:ty, $out_ty:ty, $val:ident, $body:expr) => {{ - if std::any::TypeId::of::<$in_ty>() == std::any::TypeId::of::<$out_ty>() { + if core::any::TypeId::of::<$in_ty>() == core::any::TypeId::of::<$out_ty>() { // Store the value in an `Option` so we can `take` // it after casting to `&mut dyn Any`. let mut slot = Some($val); // Re-write the `$val` ident with the downcasted value. - let $val = (&mut slot as &mut dyn std::any::Any) + let $val = (&mut slot as &mut dyn core::any::Any) .downcast_mut::>() .unwrap() .take() diff --git a/src/error.rs b/src/error.rs index 762ee1c2..adc66e47 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,7 @@ -use std::error; -use std::fmt; -use std::result; +#![allow(dead_code)] + +use core::convert; +use core::result; use crate::header; use crate::header::MaxSizeReached; @@ -14,6 +15,7 @@ use crate::uri; /// functions in this crate, but all other errors can be converted to this /// error. Consumers of this crate can typically consume and work with this form /// of error for conversions with the `?` operator. +#[derive(Debug)] pub struct Error { inner: ErrorKind, } @@ -21,6 +23,7 @@ pub struct Error { /// A `Result` typedef to use with the `http::Error` type pub type Result = result::Result; +#[derive(Debug)] enum ErrorKind { StatusCode(status::InvalidStatusCode), Method(method::InvalidMethod), @@ -31,7 +34,8 @@ enum ErrorKind { MaxSizeReached(MaxSizeReached), } -impl fmt::Debug for Error { +#[cfg(feature = "std")] +impl std::fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("http::Error") // Skip the noise of the ErrorKind enum @@ -40,13 +44,15 @@ impl fmt::Debug for Error { } } -impl fmt::Display for Error { +#[cfg(feature = "std")] +impl std::fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(self.get_ref(), f) } } -impl Error { +#[cfg(feature = "std")] +impl std::error::Error for Error { /// Return true if the underlying error has the same type as T. pub fn is(&self) -> bool { self.get_ref().is::() @@ -68,10 +74,11 @@ impl Error { } } -impl error::Error for Error { +#[cfg(feature = "std")] +impl std::error::Error for Error { // Return any available cause from the inner error. Note the inner error is // not itself the cause. - fn source(&self) -> Option<&(dyn error::Error + 'static)> { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { self.get_ref().source() } } @@ -132,13 +139,13 @@ impl From for Error { } } -impl From for Error { - fn from(err: std::convert::Infallible) -> Error { +impl From for Error { + fn from(err: convert::Infallible) -> Error { match err {} } } -#[cfg(test)] +/*#[cfg(test)] mod tests { use super::*; @@ -157,4 +164,4 @@ mod tests { panic!("Bad status allowed!"); } } -} +}*/ diff --git a/src/extensions.rs b/src/extensions.rs index c41bbfc3..0ba79c81 100644 --- a/src/extensions.rs +++ b/src/extensions.rs @@ -1,7 +1,7 @@ -use std::any::{Any, TypeId}; -use std::collections::HashMap; -use std::fmt; -use std::hash::{BuildHasherDefault, Hasher}; +use core::{any::{Any, TypeId}, fmt, hash::{BuildHasherDefault, Hasher}}; + +use alloc::boxed::Box; +use hashbrown::HashMap; type AnyMap = HashMap, BuildHasherDefault>; diff --git a/src/header/map.rs b/src/header/map.rs index 7610175b..09156106 100644 --- a/src/header/map.rs +++ b/src/header/map.rs @@ -1,10 +1,13 @@ -use std::collections::hash_map::RandomState; -use std::collections::HashMap; -use std::convert::TryFrom; -use std::hash::{BuildHasher, Hash, Hasher}; -use std::iter::{FromIterator, FusedIterator}; -use std::marker::PhantomData; -use std::{fmt, mem, ops, ptr, vec}; +use core::convert::TryFrom; +use core::iter::{FromIterator, FusedIterator}; +use core::marker::PhantomData; +use core::{fmt, mem, ops, ptr, slice}; +use core::hash::{Hash, Hasher}; + +use alloc::boxed::Box; +use alloc::vec; +use alloc::vec::Vec; +use hashbrown::HashMap; use crate::Error; @@ -116,7 +119,7 @@ pub struct IntoIter { /// associated value. #[derive(Debug)] pub struct Keys<'a, T> { - inner: ::std::slice::Iter<'a, Bucket>, + inner: slice::Iter<'a, Bucket>, } /// `HeaderMap` value iterator. @@ -209,7 +212,7 @@ pub struct ValueIterMut<'a, T> { #[derive(Debug)] pub struct ValueDrain<'a, T> { first: Option, - next: Option<::std::vec::IntoIter>, + next: Option>, lt: PhantomData<&'a mut HeaderMap>, } @@ -316,7 +319,7 @@ enum Link { enum Danger { Green, Yellow, - Red(RandomState), + Red, // TODO: no_std? } // Constants related to detecting DOS attacks. @@ -520,7 +523,7 @@ impl HeaderMap { Ok(HeaderMap { mask: (raw_cap - 1) as Size, - indices: vec![Pos::none(); raw_cap].into_boxed_slice(), + indices: alloc::vec![Pos::none(); raw_cap].into_boxed_slice(), entries: Vec::with_capacity(raw_cap), extra_values: Vec::new(), danger: Danger::Green, @@ -3526,12 +3529,12 @@ impl Pos { impl Danger { fn is_red(&self) -> bool { - matches!(*self, Danger::Red(_)) + matches!(*self, Danger::Red) } fn set_red(&mut self) { debug_assert!(self.is_yellow()); - *self = Danger::Red(RandomState::new()); + *self = Danger::Red; } fn is_yellow(&self) -> bool { @@ -3572,6 +3575,7 @@ impl fmt::Display for MaxSizeReached { } } +#[cfg(feature = "std")] impl std::error::Error for MaxSizeReached {} // ===== impl Utils ===== @@ -3612,12 +3616,6 @@ where const MASK: u64 = (MAX_SIZE as u64) - 1; let hash = match *danger { - // Safe hash - Danger::Red(ref hasher) => { - let mut h = hasher.build_hasher(); - k.hash(&mut h); - h.finish() - } // Fast hash _ => { let mut h = FnvHasher::default(); @@ -3733,6 +3731,8 @@ mod into_header_name { } mod as_header_name { + use alloc::string::String; + use super::{Entry, HdrName, HeaderMap, HeaderName, InvalidHeaderName, MaxSizeReached}; /// A marker trait used to identify values that can be used as search keys diff --git a/src/header/name.rs b/src/header/name.rs index 3d563f4e..5d39e917 100644 --- a/src/header/name.rs +++ b/src/header/name.rs @@ -1,14 +1,10 @@ +use core::{borrow::Borrow, convert::TryFrom, fmt, mem::MaybeUninit, str::FromStr}; +use core::hash::{Hash, Hasher}; + use crate::byte_str::ByteStr; +use alloc::{string::String, vec::Vec}; use bytes::{Bytes, BytesMut}; -use std::borrow::Borrow; -use std::convert::TryFrom; -use std::error::Error; -use std::fmt; -use std::hash::{Hash, Hasher}; -use std::mem::MaybeUninit; -use std::str::FromStr; - /// Represents an HTTP header field name /// /// Header field names identify the header. Header sets may include multiple @@ -89,7 +85,7 @@ macro_rules! standard_headers { match *self { // Safety: test_parse_standard_headers ensures these &[u8]s are &str-safe. $( - StandardHeader::$konst => unsafe { std::str::from_utf8_unchecked( $name_bytes ) }, + StandardHeader::$konst => unsafe { core::str::from_utf8_unchecked( $name_bytes ) }, )+ } } @@ -118,7 +114,7 @@ macro_rules! standard_headers { assert_eq!(HeaderName::from_bytes(name_bytes).unwrap(), HeaderName::from(std)); // Test upper case - let upper = std::str::from_utf8(name_bytes).expect("byte string constants are all utf-8").to_uppercase(); + let upper = core::str::from_utf8(name_bytes).expect("byte string constants are all utf-8").to_uppercase(); assert_eq!(HeaderName::from_bytes(upper.as_bytes()).unwrap(), HeaderName::from(std)); } } @@ -126,7 +122,7 @@ macro_rules! standard_headers { #[test] fn test_standard_headers_into_bytes() { for &(std, name_bytes) in TEST_HEADERS { - let name = std::str::from_utf8(name_bytes).unwrap(); + let name = core::str::from_utf8(name_bytes).unwrap(); let std = HeaderName::from(std); // Test lower case let bytes: Bytes = @@ -1516,7 +1512,8 @@ impl fmt::Display for InvalidHeaderName { } } -impl Error for InvalidHeaderName {} +#[cfg(feature = "std")] +impl std::error::Error for InvalidHeaderName {} // ===== HdrName ===== @@ -1668,11 +1665,13 @@ fn uninit_u8_array() -> [MaybeUninit; SCRATCH_BUF_SIZE] { // Safety: All elements of `slice` must be initialized to prevent // undefined behavior. unsafe fn slice_assume_init(slice: &[MaybeUninit]) -> &[T] { - &*(slice as *const [MaybeUninit] as *const [T]) + unsafe { &*(slice as *const [MaybeUninit] as *const [T]) } } #[cfg(test)] mod tests { + use alloc::vec; + use self::StandardHeader::Vary; use super::*; @@ -1705,7 +1704,7 @@ mod tests { let long = &ONE_TOO_LONG[0..super::super::MAX_HEADER_NAME_LEN]; - let long_str = std::str::from_utf8(long).unwrap(); + let long_str = core::str::from_utf8(long).unwrap(); assert_eq!(HeaderName::from_static(long_str), long_str); // shouldn't panic! assert!( @@ -1722,7 +1721,7 @@ mod tests { #[should_panic] fn test_static_invalid_name_lengths() { // Safety: ONE_TOO_LONG contains only the UTF-8 safe, single-byte codepoint b'a'. - let _ = HeaderName::from_static(unsafe { std::str::from_utf8_unchecked(ONE_TOO_LONG) }); + let _ = HeaderName::from_static(unsafe { core::str::from_utf8_unchecked(ONE_TOO_LONG) }); } #[test] diff --git a/src/header/value.rs b/src/header/value.rs index 4813f6fd..6adcacb2 100644 --- a/src/header/value.rs +++ b/src/header/value.rs @@ -1,12 +1,13 @@ +use core::convert::TryFrom; +use core::{cmp, fmt}; +use core::hash::{Hash, Hasher}; +use core::mem; +use core::str::FromStr; + +use alloc::string::String; +use alloc::vec::Vec; use bytes::{Bytes, BytesMut}; -use std::convert::TryFrom; -use std::error::Error; -use std::fmt::Write; -use std::hash::{Hash, Hasher}; -use std::str::FromStr; -use std::{cmp, fmt, mem, str}; - use crate::header::name::HeaderName; /// Represents an HTTP header field value. @@ -234,7 +235,7 @@ impl HeaderValue { } fn from_shared(src: Bytes) -> Result { - HeaderValue::try_from_generic(src, std::convert::identity) + HeaderValue::try_from_generic(src, core::convert::identity) } fn try_from_generic, F: FnOnce(T) -> Bytes>( @@ -274,7 +275,7 @@ impl HeaderValue { } } - unsafe { Ok(str::from_utf8_unchecked(bytes)) } + unsafe { Ok(core::str::from_utf8_unchecked(bytes)) } } /// Returns the length of `self`. @@ -393,7 +394,7 @@ impl fmt::Debug for HeaderValue { for (i, &b) in bytes.iter().enumerate() { if !is_visible_ascii(b) || b == b'"' { if from != i { - f.write_str(unsafe { str::from_utf8_unchecked(&bytes[from..i]) })?; + f.write_str(unsafe { core::str::from_utf8_unchecked(&bytes[from..i]) })?; } if b == b'"' { f.write_str("\\\"")?; @@ -404,7 +405,7 @@ impl fmt::Debug for HeaderValue { } } - f.write_str(unsafe { str::from_utf8_unchecked(&bytes[from..]) })?; + f.write_str(unsafe { core::str::from_utf8_unchecked(&bytes[from..]) })?; f.write_str("\"") } } @@ -424,6 +425,8 @@ macro_rules! from_integers { ($($name:ident: $t:ident => $max_len:expr),*) => {$( impl From<$t> for HeaderValue { fn from(num: $t) -> HeaderValue { + use core::fmt::Write; + let mut buf = if mem::size_of::() - 1 < $max_len { // On 32bit platforms, BytesMut max inline size // is 15 bytes, but the $max_len could be bigger. @@ -455,11 +458,13 @@ macro_rules! from_integers { #[test] fn $name() { + use alloc::string::ToString; + let n: $t = 55; let val = HeaderValue::from(n); assert_eq!(val, &n.to_string()); - let n = ::std::$t::MAX; + let n = ::core::primitive::$t::MAX; let val = HeaderValue::from(n); assert_eq!(val, &n.to_string()); } @@ -620,7 +625,8 @@ impl fmt::Display for InvalidHeaderValue { } } -impl Error for InvalidHeaderValue {} +#[cfg(feature = "std")] +impl std::error::Error for InvalidHeaderValue {} impl fmt::Display for ToStrError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -628,7 +634,8 @@ impl fmt::Display for ToStrError { } } -impl Error for ToStrError {} +#[cfg(feature = "std")] +impl std::error::Error for ToStrError {} // ===== PartialEq / PartialOrd ===== @@ -795,7 +802,7 @@ impl<'a> PartialOrd for &'a str { #[test] fn test_try_from() { - HeaderValue::try_from(vec![127]).unwrap_err(); + HeaderValue::try_from(alloc::vec![127]).unwrap_err(); } #[test] @@ -808,11 +815,11 @@ fn test_debug() { for &(value, expected) in cases { let val = HeaderValue::from_bytes(value.as_bytes()).unwrap(); - let actual = format!("{:?}", val); + let actual = alloc::format!("{:?}", val); assert_eq!(expected, actual); } let mut sensitive = HeaderValue::from_static("password"); sensitive.set_sensitive(true); - assert_eq!("Sensitive", format!("{:?}", sensitive)); + assert_eq!("Sensitive", alloc::format!("{:?}", sensitive)); } diff --git a/src/lib.rs b/src/lib.rs index 0ab5bdfd..1cce5c8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -155,9 +155,10 @@ #![deny(warnings, missing_docs, missing_debug_implementations)] -//#![cfg_attr(not(feature = "std"), no_std)] -#[cfg(not(feature = "std"))] -compile_error!("`std` feature currently required, support for `no_std` may be added later"); +#![cfg_attr(not(feature = "std"), no_std)] + +#![cfg(not(feature = "std"))] +extern crate alloc; #[cfg(test)] #[macro_use] diff --git a/src/method.rs b/src/method.rs index 3d45ef9f..d2e40db0 100644 --- a/src/method.rs +++ b/src/method.rs @@ -15,14 +15,13 @@ //! assert_eq!(Method::POST.as_str(), "POST"); //! ``` +use core::convert::TryFrom; +use core::fmt; +use core::str::FromStr; + use self::extension::{AllocatedExtension, InlineExtension}; use self::Inner::*; -use std::convert::TryFrom; -use std::error::Error; -use std::str::FromStr; -use std::{fmt, str}; - /// The Request Method (VERB) /// /// This type also contains constants for a number of common HTTP methods such @@ -302,11 +301,13 @@ impl fmt::Display for InvalidMethod { } } -impl Error for InvalidMethod {} +#[cfg(feature = "std")] +impl std::error::Error for InvalidMethod {} mod extension { + use alloc::{boxed::Box, vec::Vec}; + use super::InvalidMethod; - use std::str; #[derive(Clone, PartialEq, Eq, Hash)] // Invariant: the first self.1 bytes of self.0 are valid UTF-8. @@ -334,13 +335,13 @@ mod extension { let InlineExtension(ref data, len) = self; // Safety: the invariant of InlineExtension ensures that the first // len bytes of data contain valid UTF-8. - unsafe { str::from_utf8_unchecked(&data[..*len as usize]) } + unsafe { core::str::from_utf8_unchecked(&data[..*len as usize]) } } } impl AllocatedExtension { pub fn new(src: &[u8]) -> Result { - let mut data: Vec = vec![0; src.len()]; + let mut data: Vec = alloc::vec![0; src.len()]; write_checked(src, &mut data)?; @@ -352,7 +353,7 @@ mod extension { pub fn as_str(&self) -> &str { // Safety: the invariant of AllocatedExtension ensures that self.0 // contains valid UTF-8. - unsafe { str::from_utf8_unchecked(&self.0) } + unsafe { core::str::from_utf8_unchecked(&self.0) } } } @@ -421,6 +422,8 @@ mod extension { #[cfg(test)] mod test { + use alloc::string::ToString; + use super::*; #[test] diff --git a/src/request.rs b/src/request.rs index 324b676c..be58fde9 100644 --- a/src/request.rs +++ b/src/request.rs @@ -52,9 +52,9 @@ //! } //! ``` -use std::any::Any; -use std::convert::TryInto; -use std::fmt; +use core::any::Any; +use core::convert::TryInto; +use core::fmt; use crate::header::{HeaderMap, HeaderName, HeaderValue}; use crate::method::Method; diff --git a/src/response.rs b/src/response.rs index ab9e49bc..17f5d7f1 100644 --- a/src/response.rs +++ b/src/response.rs @@ -61,9 +61,9 @@ //! // ... //! ``` -use std::any::Any; -use std::convert::TryInto; -use std::fmt; +use core::any::Any; +use core::convert::TryInto; +use core::fmt; use crate::header::{HeaderMap, HeaderName, HeaderValue}; use crate::status::StatusCode; diff --git a/src/status.rs b/src/status.rs index 16896e4a..20dd56cf 100644 --- a/src/status.rs +++ b/src/status.rs @@ -14,11 +14,9 @@ //! assert!(StatusCode::OK.is_success()); //! ``` -use std::convert::TryFrom; -use std::error::Error; -use std::fmt; -use std::num::NonZeroU16; -use std::str::FromStr; +use core::{convert::TryFrom, fmt, num::NonZeroU16, str::FromStr}; + +use alloc::borrow::ToOwned; /// An HTTP status code (`status-code` in RFC 9110 et al.). /// @@ -542,7 +540,8 @@ impl fmt::Display for InvalidStatusCode { } } -impl Error for InvalidStatusCode {} +#[cfg(feature = "std")] +impl std::error::Error for InvalidStatusCode {} // A string of packed 3-ASCII-digit status code values for the supported range // of [100, 999] (900 codes, 2700 bytes). diff --git a/src/uri/authority.rs b/src/uri/authority.rs index 07aa6795..b2bc8356 100644 --- a/src/uri/authority.rs +++ b/src/uri/authority.rs @@ -1,8 +1,11 @@ -use std::convert::TryFrom; -use std::hash::{Hash, Hasher}; -use std::str::FromStr; -use std::{cmp, fmt, str}; - +use core::convert::TryFrom; +use core::fmt; +use core::str::FromStr; +use core::{cmp, hash::Hasher}; +use core::hash::Hash; + +use alloc::string::String; +use alloc::vec::Vec; use bytes::Bytes; use super::{ErrorKind, InvalidUri, Port, URI_CHARS}; @@ -530,6 +533,8 @@ where #[cfg(test)] mod tests { + use alloc::string::ToString; + use super::*; #[test] diff --git a/src/uri/builder.rs b/src/uri/builder.rs index d5f7f49b..c69e1437 100644 --- a/src/uri/builder.rs +++ b/src/uri/builder.rs @@ -1,4 +1,4 @@ -use std::convert::TryInto; +use core::convert::TryInto; use super::{Authority, Parts, PathAndQuery, Scheme}; use crate::Uri; @@ -182,10 +182,10 @@ mod tests { fn build_from_string() { for i in 1..10 { let uri = Builder::new() - .path_and_query(format!("/foo?a={}", i)) + .path_and_query(alloc::format!("/foo?a={}", i)) .build() .unwrap(); - let expected_query = format!("a={}", i); + let expected_query = alloc::format!("a={}", i); assert_eq!(uri.path(), "/foo"); assert_eq!(uri.query(), Some(expected_query.as_str())); } @@ -194,9 +194,9 @@ mod tests { #[test] fn build_from_string_ref() { for i in 1..10 { - let p_a_q = format!("/foo?a={}", i); + let p_a_q = alloc::format!("/foo?a={}", i); let uri = Builder::new().path_and_query(&p_a_q).build().unwrap(); - let expected_query = format!("a={}", i); + let expected_query = alloc::format!("a={}", i); assert_eq!(uri.path(), "/foo"); assert_eq!(uri.query(), Some(expected_query.as_str())); } diff --git a/src/uri/mod.rs b/src/uri/mod.rs index 767f0743..cd1f2e9f 100644 --- a/src/uri/mod.rs +++ b/src/uri/mod.rs @@ -22,16 +22,18 @@ //! assert_eq!(uri.path(), "/install.html"); //! ``` +use core::convert::TryFrom; +use core::fmt; +use core::str::FromStr; +use core::hash::{Hash, Hasher}; + use crate::byte_str::ByteStr; -use std::convert::TryFrom; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; use bytes::Bytes; -use std::error::Error; -use std::fmt; -use std::hash::{Hash, Hasher}; -use std::str::{self, FromStr}; - use self::scheme::Scheme2; pub use self::authority::Authority; @@ -1083,7 +1085,8 @@ impl fmt::Display for InvalidUri { } } -impl Error for InvalidUri {} +#[cfg(feature = "std")] +impl std::error::Error for InvalidUri {} impl fmt::Display for InvalidUriParts { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -1091,7 +1094,8 @@ impl fmt::Display for InvalidUriParts { } } -impl Error for InvalidUriParts {} +#[cfg(feature = "std")] +impl std::error::Error for InvalidUriParts {} impl Hash for Uri { fn hash(&self, state: &mut H) diff --git a/src/uri/path.rs b/src/uri/path.rs index 6a2f1e1e..85427b6f 100644 --- a/src/uri/path.rs +++ b/src/uri/path.rs @@ -1,7 +1,6 @@ -use std::convert::TryFrom; -use std::str::FromStr; -use std::{cmp, fmt, hash, str}; +use core::{cmp, convert::TryFrom, fmt, hash::{Hash, Hasher}, str::FromStr}; +use alloc::{string::String, vec::Vec}; use bytes::Bytes; use super::{ErrorKind, InvalidUri}; @@ -345,8 +344,8 @@ impl fmt::Display for PathAndQuery { } } -impl hash::Hash for PathAndQuery { - fn hash(&self, state: &mut H) { +impl Hash for PathAndQuery { + fn hash(&self, state: &mut H) { self.data.hash(state); } } @@ -455,6 +454,8 @@ impl PartialOrd for String { #[cfg(test)] mod tests { + use alloc::string::ToString; + use super::*; #[test] @@ -565,6 +566,6 @@ mod tests { } fn pq(s: &str) -> PathAndQuery { - s.parse().expect(&format!("parsing {}", s)) + s.parse().expect(&alloc::format!("parsing {}", s)) } } diff --git a/src/uri/port.rs b/src/uri/port.rs index 8f5c5f3f..b695c550 100644 --- a/src/uri/port.rs +++ b/src/uri/port.rs @@ -1,4 +1,4 @@ -use std::fmt; +use core::fmt; use super::{ErrorKind, InvalidUri}; @@ -112,6 +112,8 @@ impl PartialEq> for u16 { #[cfg(test)] mod tests { + use alloc::string::String; + use super::*; #[test] diff --git a/src/uri/scheme.rs b/src/uri/scheme.rs index dbcc8c3f..c2d5624f 100644 --- a/src/uri/scheme.rs +++ b/src/uri/scheme.rs @@ -1,8 +1,7 @@ -use std::convert::TryFrom; -use std::fmt; -use std::hash::{Hash, Hasher}; -use std::str::FromStr; +use core::{convert::TryFrom, fmt, str::FromStr}; +use core::hash::{Hash, Hasher}; +use alloc::boxed::Box; use bytes::Bytes; use super::{ErrorKind, InvalidUri}; @@ -356,6 +355,6 @@ mod test { } fn scheme(s: &str) -> Scheme { - s.parse().expect(&format!("Invalid scheme: {}", s)) + s.parse().expect(&alloc::format!("Invalid scheme: {}", s)) } } diff --git a/src/uri/tests.rs b/src/uri/tests.rs index 719cb94e..204a86f9 100644 --- a/src/uri/tests.rs +++ b/src/uri/tests.rs @@ -1,4 +1,6 @@ -use std::str::FromStr; +use core::str::FromStr; + +use alloc::string::{String, ToString}; use super::{ErrorKind, InvalidUri, Port, Uri, URI_CHARS}; @@ -442,9 +444,9 @@ fn test_uri_parse_error() { #[test] fn test_max_uri_len() { - let mut uri = vec![]; + let mut uri = alloc::vec![]; uri.extend(b"http://localhost/"); - uri.extend(vec![b'a'; 70 * 1024]); + uri.extend(alloc::vec![b'a'; 70 * 1024]); let uri = String::from_utf8(uri).unwrap(); let res: Result = uri.parse(); @@ -454,8 +456,8 @@ fn test_max_uri_len() { #[test] fn test_overflowing_scheme() { - let mut uri = vec![]; - uri.extend(vec![b'a'; 256]); + let mut uri = alloc::vec![]; + uri.extend(alloc::vec![b'a'; 256]); uri.extend(b"://localhost/"); let uri = String::from_utf8(uri).unwrap(); @@ -466,8 +468,8 @@ fn test_overflowing_scheme() { #[test] fn test_max_length_scheme() { - let mut uri = vec![]; - uri.extend(vec![b'a'; 64]); + let mut uri = alloc::vec![]; + uri.extend(alloc::vec![b'a'; 64]); uri.extend(b"://localhost/"); let uri = String::from_utf8(uri).unwrap(); @@ -478,7 +480,7 @@ fn test_max_length_scheme() { #[test] fn test_uri_to_path_and_query() { - let cases = vec![ + let cases = alloc::vec![ ("/", "/"), ("/foo?bar", "/foo?bar"), ("/foo?bar#nope", "/foo?bar"), diff --git a/src/version.rs b/src/version.rs index d8b71306..436ca7df 100644 --- a/src/version.rs +++ b/src/version.rs @@ -19,7 +19,7 @@ //! println!("{:?}", http2); //! ``` -use std::fmt; +use core::fmt; /// Represents a version of the HTTP spec. #[derive(PartialEq, PartialOrd, Copy, Clone, Eq, Ord, Hash)] diff --git a/tests/header_map_fuzz.rs b/tests/header_map_fuzz.rs index 40db0494..aae5a6c4 100644 --- a/tests/header_map_fuzz.rs +++ b/tests/header_map_fuzz.rs @@ -1,3 +1,4 @@ +use hashbrown::HashMap; use http::header::*; use http::*; @@ -6,8 +7,6 @@ use rand::rngs::StdRng; use rand::seq::SliceRandom; use rand::{Rng, SeedableRng}; -use std::collections::HashMap; - #[cfg(not(miri))] #[test] fn header_map_fuzz() {