Skip to content

hyperium/http

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

this provides an implementation of `Hash` for the `PathAndQuery`
structure.

an example program is shown below, demonstrating why this would be a
desirable improvement in ergonomics.

rust playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=cb5e9eb3afc705d7760af0fe695fe3a5

```rust
 //! A small example program demonstrating the ergonomics of [`Hash::hash`]ing
 // structures that contain a [`http::uri::PathAndQuery`] in an inner field.

 #![allow(dead_code)]

 use {
     http::uri::PathAndQuery,
     std:#️⃣:{Hash, Hasher},
 };

 /// A structure that *can* be hashed.
 ///
 /// Note that it must convert the [`PathAndQuery`] to a string in order to be
 /// derivably [`Hash`]able.
 #[derive(Hash)]
 struct CanBeHashed {
     inner: String,
 }

 impl CanBeHashed {
     pub fn new(path_and_query: PathAndQuery) -> Self {
         let inner = path_and_query.as_str().to_owned();
         Self { inner }
     }

     pub fn path_and_query(&self) -> PathAndQuery {
         // We can derive a `Hash` implementation, but in order to access the
         // path and query, we have to parse the data again.
         self
             .inner
             .parse::<PathAndQuery>()
             .expect("inner data is a valid `PathAndQuery`")
     }
 }

 /// A structure that *cannot* be derivably hashed.
 ///
 /// If we uncomment the derivation below, and comment out the manual
 /// implementation provided later, we will see the following error:
 ///
 /// ```ignore
 /// error[E0277]: the trait bound `PathAndQuery: Hash` is not satisfied
 ///   --> src/main.rs:26:5
 ///    |
 /// 24 | #[derive(Hash)]
 ///    |          ---- in this derive macro expansion
 /// 25 | struct CannotBeHashed {
 /// 26 |     inner: PathAndQuery,
 ///    |     ^^^^^^^^^^^^^^^^^^^ the trait `Hash` is not implemented for `PathAndQuery`
 /// ```
 // #[derive(Hash)]
 struct CannotBeHashed {
     inner: PathAndQuery,
 }

 impl CannotBeHashed {
     fn new(inner: PathAndQuery) -> Self {
         Self { inner }
     }

     pub fn path_and_query(&self) -> &PathAndQuery {
         // The path and query can be cheaply accessed as such...
         &self.inner
     }
 }

 impl Hash for CannotBeHashed {
     fn hash<H: Hasher>(&self, state: &mut H) {
         // ...but we must manually implement `Hash`, casting the `PathAndQuery`
         // into a string slice.
         let Self { inner } = self;
         inner.as_str().hash(state);
     }
 }

 // NB: a clever reader may note `PathAndQuery::from_maybe_shared`, which could
 // reduce copying overhead! This still entails iterating through the buffer
 // to find the beginning of the query component, unfortunately.  :,(

 fn main() {}
```
f0ba97f

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
December 5, 2022 15:18
April 10, 2021 08:43
src
January 19, 2023 12:44
December 5, 2022 15:18
April 27, 2021 17:54
March 16, 2017 08:57
June 6, 2022 15:06
March 16, 2017 08:57
March 16, 2017 08:57

HTTP

A general purpose library of common HTTP types

CI Crates.io Documentation

More information about this crate can be found in the crate documentation.

Usage

To use http, first add this to your Cargo.toml:

[dependencies]
http = "0.2"

Next, add this to your crate:

use http::{Request, Response};

fn main() {
    // ...
}

Examples

Create an HTTP request:

use http::Request;

fn main() {
    let request = Request::builder()
      .uri("https://www.rust-lang.org/")
      .header("User-Agent", "awesome/1.0")
      .body(())
      .unwrap();
}

Create an HTTP response:

use http::{Response, StatusCode};

fn main() {
    let response = Response::builder()
      .status(StatusCode::MOVED_PERMANENTLY)
      .header("Location", "https://www.rust-lang.org/install.html")
      .body(())
      .unwrap();
}

Supported Rust Versions

This project follows the Tokio MSRV and is currently set to 1.49.

License

Licensed under either of

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.