diff --git a/.travis.yml b/.travis.yml index 3713cad..9a46aa5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,12 @@ cache: - target/debug/deps - target/debug/build +script: + - cargo build + - cargo test --verbose + - cargo build --verbose --no-default-features + - cargo test --verbose --no-default-features + notifications: email: false diff --git a/Cargo.toml b/Cargo.toml index e269c5b..fd8b02f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,10 @@ license = "MIT" description = "A tiny, safe, speedy, zero-copy HTTP/1.x parser." repository = "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/seanmonstar/httparse" +[features] +default = ["no_std"] +no_std = [] + [dev-dependencies] pico-sys = "0.0" diff --git a/src/iter.rs b/src/iter.rs index 425e6ec..1a9113f 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -1,5 +1,9 @@ +#[cfg(feature = "no_std")] use core::slice; +#[cfg(not(feature = "no_std"))] +use std::slice; + pub struct Bytes<'a> { slice: &'a [u8], pos: usize diff --git a/src/lib.rs b/src/lib.rs index 4cbccb2..a82db3e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![cfg_attr(not(test),no_std)] +#![cfg_attr(all(feature = "no_std", not(test)), no_std)] #![cfg_attr(test, deny(warnings))] #![deny(missing_docs)] //! # httparse @@ -16,7 +16,12 @@ #[cfg(test)] extern crate core; -use core::{str, slice}; +#[cfg(feature = "no_std")] +use core::{fmt, result, str, slice}; + +#[cfg(not(feature = "no_std"))] +use std::{fmt, result, str, slice}; + use iter::Bytes; mod iter; @@ -111,27 +116,41 @@ pub enum Error { Version, } -impl ::core::fmt::Display for Error { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { +impl Error { + #[inline] + fn description_str(&self) -> &'static str { match *self { - Error::HeaderName => f.write_str("invalid header name"), - Error::HeaderValue => f.write_str("invalid header value"), - Error::NewLine => f.write_str("invalid new line"), - Error::Status => f.write_str("invalid response status"), - Error::Token => f.write_str("invalid token"), - Error::TooManyHeaders => f.write_str("too many headers"), - Error::Version => f.write_str("invalid HTTP version"), + Error::HeaderName => "invalid header name", + Error::HeaderValue => "invalid header value", + Error::NewLine => "invalid new line", + Error::Status => "invalid response status", + Error::Token => "invalid token", + Error::TooManyHeaders => "too many headers", + Error::Version => "invalid HTTP version", } } } +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.description_str()) + } +} + +#[cfg(not(feature = "no_std"))] +impl std::error::Error for Error { + fn description(&self) -> &str { + self.description_str() + } +} + /// An error in parsing a chunk size. // Note: Move this into the error enum once v2.0 is released. #[derive(Debug, PartialEq, Eq)] pub struct InvalidChunkSize; -impl ::core::fmt::Display for InvalidChunkSize { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { +impl fmt::Display for InvalidChunkSize { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("invalid chunk size") } } @@ -141,7 +160,7 @@ impl ::core::fmt::Display for InvalidChunkSize { /// If the input is invalid, an `Error` will be returned. Note that incomplete /// data is not considered invalid, and so will not return an error, but rather /// a `Ok(Status::Partial)`. -pub type Result = ::core::result::Result, Error>; +pub type Result = result::Result, Error>; /// The result of a successful parse pass. /// @@ -581,7 +600,7 @@ fn parse_headers_iter<'a, 'b>(headers: &mut &mut [Header<'a>], bytes: &'b mut By /// Ok(httparse::Status::Complete((3, 4)))); /// ``` pub fn parse_chunk_size(buf: &[u8]) - -> ::core::result::Result, InvalidChunkSize> { + -> result::Result, InvalidChunkSize> { const RADIX: u64 = 16; let mut bytes = Bytes::new(buf); let mut size = 0;