Skip to content

Commit

Permalink
Turn crate into no_std using core + alloc
Browse files Browse the repository at this point in the history
Extensions are also made an optional feature to not require depending on HashMap
  • Loading branch information
olanod committed Aug 3, 2022
1 parent 34a9d6b commit 09c0e28
Show file tree
Hide file tree
Showing 21 changed files with 338 additions and 242 deletions.
8 changes: 8 additions & 0 deletions Cargo.toml
Expand Up @@ -27,6 +27,14 @@ rust-version = "1.49.0"
bytes = "1"
fnv = "1.0.5"
itoa = "1"
ahash = { version = "0.7", default-features = false }
hashbrown = { version = "0.12", optional = true }

[features]
default = ["std", "extensions"]
std = []
hashmap = ["hashbrown"]
extensions = ["hashmap"]

[dev-dependencies]
indexmap = "<=1.8"
Expand Down
4 changes: 2 additions & 2 deletions src/byte_str.rs
@@ -1,6 +1,6 @@
use alloc::string::String;
use bytes::Bytes;

use std::{ops, str};
use core::{ops, str};

#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub(crate) struct ByteStr {
Expand Down
8 changes: 4 additions & 4 deletions src/convert.rs
@@ -1,17 +1,17 @@
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>() {
($in_ty:ty, $out_ty:ty, $val:ident, $body:expr) => {{
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::<Option<$out_ty>>()
.unwrap()
.take()
.unwrap();
// Run the $body in scope of the replaced val.
$body
}
})
}};
}
35 changes: 28 additions & 7 deletions src/error.rs
@@ -1,6 +1,7 @@
use core::fmt;
use core::result;
#[cfg(feature = "std")]
use std::error;
use std::fmt;
use std::result;

use crate::header;
use crate::method;
Expand Down Expand Up @@ -31,19 +32,38 @@ enum ErrorKind {

impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use ErrorKind::*;
let e: &dyn fmt::Debug = match self.inner {
StatusCode(ref e) => e,
Method(ref e) => e,
Uri(ref e) => e,
UriParts(ref e) => e,
HeaderName(ref e) => e,
HeaderValue(ref e) => e,
};
f.debug_tuple("http::Error")
// Skip the noise of the ErrorKind enum
.field(&self.get_ref())
.field(e)
.finish()
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.get_ref(), f)
use ErrorKind::*;
let e: &dyn fmt::Display = match self.inner {
StatusCode(ref e) => e,
Method(ref e) => e,
Uri(ref e) => e,
UriParts(ref e) => e,
HeaderName(ref e) => e,
HeaderValue(ref e) => e,
};
fmt::Display::fmt(e, f)
}
}

#[cfg(feature = "std")]
impl Error {
/// Return true if the underlying error has the same type as T.
pub fn is<T: error::Error + 'static>(&self) -> bool {
Expand All @@ -65,6 +85,7 @@ impl Error {
}
}

#[cfg(feature = "std")]
impl error::Error for Error {
// Return any available cause from the inner error. Note the inner error is
// not itself the cause.
Expand Down Expand Up @@ -121,13 +142,13 @@ impl From<header::InvalidHeaderValue> for Error {
}
}

impl From<std::convert::Infallible> for Error {
fn from(err: std::convert::Infallible) -> Error {
impl From<core::convert::Infallible> for Error {
fn from(err: core::convert::Infallible) -> Error {
match err {}
}
}

#[cfg(test)]
#[cfg(all(test, feature = "std"))]
mod tests {
use super::*;

Expand Down
26 changes: 12 additions & 14 deletions src/extensions.rs
@@ -1,7 +1,9 @@
use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::fmt;
use std::hash::{BuildHasherDefault, Hasher};
use core::any::{Any, TypeId};
use core::fmt;
use core::hash::{BuildHasherDefault, Hasher};
use hashbrown::HashMap;

use alloc::boxed::Box;

type AnyMap = HashMap<TypeId, Box<dyn Any + Send + Sync>, BuildHasherDefault<IdHasher>>;

Expand Down Expand Up @@ -166,9 +168,7 @@ impl Extensions {
/// ```
#[inline]
pub fn is_empty(&self) -> bool {
self.map
.as_ref()
.map_or(true, |map| map.is_empty())
self.map.as_ref().map_or(true, |map| map.is_empty())
}

/// Get the numer of extensions available.
Expand All @@ -184,28 +184,26 @@ impl Extensions {
/// ```
#[inline]
pub fn len(&self) -> usize {
self.map
.as_ref()
.map_or(0, |map| map.len())
self.map.as_ref().map_or(0, |map| map.len())
}

/// Extends `self` with another `Extensions`.
///
/// If an instance of a specific type exists in both, the one in `self` is overwritten with the
/// one from `other`.
///
///
/// # Example
///
///
/// ```
/// # use http::Extensions;
/// let mut ext_a = Extensions::new();
/// ext_a.insert(8u8);
/// ext_a.insert(16u16);
///
///
/// let mut ext_b = Extensions::new();
/// ext_b.insert(4u8);
/// ext_b.insert("hello");
///
///
/// ext_a.extend(ext_b);
/// assert_eq!(ext_a.len(), 3);
/// assert_eq!(ext_a.get::<u8>(), Some(&4u8));
Expand Down

0 comments on commit 09c0e28

Please sign in to comment.