Skip to content

Commit 8de3fee

Browse files
authored
Merge pull request #57 from yoshuawuyts/trailers
initialize trailers
2 parents 432ecfb + 37e261f commit 8de3fee

File tree

5 files changed

+135
-2
lines changed

5 files changed

+135
-2
lines changed

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ default = []
1616
hyperium_http = ["http"]
1717

1818
[dependencies]
19-
async-std = { version = "1.4.0", default-features = false, features = ["std"] }
19+
async-std = { version = "1.4.0", features = ["unstable"] }
2020
cookie = "0.12.0"
2121
infer = "0.1.2"
2222
pin-project-lite = "0.1.0"
@@ -28,4 +28,3 @@ http = { version = "0.2.0", optional = true }
2828

2929
[dev-dependencies]
3030
http = "0.2.0"
31-
async-std = "1.4.0"

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ mod method;
120120
mod request;
121121
mod response;
122122
mod status_code;
123+
mod trailers;
123124
mod version;
124125

125126
pub use body::Body;
@@ -128,6 +129,7 @@ pub use method::Method;
128129
pub use request::Request;
129130
pub use response::Response;
130131
pub use status_code::StatusCode;
132+
pub use trailers::Trailers;
131133
pub use version::Version;
132134

133135
#[doc(inline)]

src/request.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use async_std::io::{self, BufRead, Read};
2+
use async_std::sync;
23

34
use std::mem;
45
use std::pin::Pin;
@@ -9,6 +10,7 @@ use crate::headers::{
910
};
1011
use crate::mime::Mime;
1112
use crate::Cookie;
13+
use crate::Trailers;
1214
use crate::{Body, Method, Url, Version};
1315

1416
pin_project_lite::pin_project! {
@@ -28,6 +30,8 @@ pin_project_lite::pin_project! {
2830
url: Url,
2931
headers: Headers,
3032
version: Option<Version>,
33+
sender: sync::Sender<io::Result<Trailers>>,
34+
receiver: sync::Receiver<io::Result<Trailers>>,
3135
#[pin]
3236
body: Body,
3337
}
@@ -36,12 +40,15 @@ pin_project_lite::pin_project! {
3640
impl Request {
3741
/// Create a new request.
3842
pub fn new(method: Method, url: Url) -> Self {
43+
let (sender, receiver) = sync::channel(1);
3944
Self {
4045
method,
4146
url,
4247
headers: Headers::new(),
4348
version: None,
4449
body: Body::empty(),
50+
sender,
51+
receiver,
4552
}
4653
}
4754

@@ -368,6 +375,16 @@ impl Request {
368375
.unwrap();
369376
}
370377

378+
/// Sends trailers to the a receiver.
379+
pub async fn send_trailers(&self, trailers: io::Result<Trailers>) {
380+
self.sender.send(trailers).await;
381+
}
382+
383+
/// Receive trailers from a sender.
384+
pub async fn recv_trailers(&self) -> Option<io::Result<Trailers>> {
385+
self.receiver.recv().await
386+
}
387+
371388
/// An iterator visiting all header pairs in arbitrary order.
372389
pub fn iter<'a>(&'a self) -> headers::Iter<'a> {
373390
self.headers.iter()

src/response.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use async_std::io::{self, BufRead, Read};
2+
use async_std::sync;
23

34
use std::mem;
45
use std::pin::Pin;
@@ -8,6 +9,7 @@ use crate::headers::{
89
self, HeaderName, HeaderValue, Headers, Names, ToHeaderValues, Values, CONTENT_TYPE,
910
};
1011
use crate::mime::Mime;
12+
use crate::Trailers;
1113
use crate::{Body, Cookie, StatusCode, Version};
1214

1315
pin_project_lite::pin_project! {
@@ -30,6 +32,8 @@ pin_project_lite::pin_project! {
3032
status: StatusCode,
3133
headers: Headers,
3234
version: Option<Version>,
35+
sender: sync::Sender<io::Result<Trailers>>,
36+
receiver: sync::Receiver<io::Result<Trailers>>,
3337
#[pin]
3438
body: Body,
3539
}
@@ -38,11 +42,14 @@ pin_project_lite::pin_project! {
3842
impl Response {
3943
/// Create a new response.
4044
pub fn new(status: StatusCode) -> Self {
45+
let (sender, receiver) = sync::channel(1);
4146
Self {
4247
status,
4348
headers: Headers::new(),
4449
version: None,
4550
body: Body::empty(),
51+
sender,
52+
receiver,
4653
}
4754
}
4855

@@ -321,6 +328,16 @@ impl Response {
321328
.unwrap();
322329
}
323330

331+
/// Sends trailers to the a receiver.
332+
pub async fn send_trailers(&self, trailers: io::Result<Trailers>) {
333+
self.sender.send(trailers).await;
334+
}
335+
336+
/// Receive trailers from a sender.
337+
pub async fn recv_trailers(&self) -> Option<io::Result<Trailers>> {
338+
self.receiver.recv().await
339+
}
340+
324341
/// An iterator visiting all header pairs in arbitrary order.
325342
pub fn iter<'a>(&'a self) -> headers::Iter<'a> {
326343
self.headers.iter()

src/trailers.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
use crate::headers::{
2+
HeaderName, HeaderValue, Headers, Iter, IterMut, Names, ToHeaderValues, Values,
3+
};
4+
5+
use std::io;
6+
use std::ops::{Deref, DerefMut};
7+
8+
/// A collection of trailing HTTP headers.
9+
#[derive(Debug)]
10+
pub struct Trailers {
11+
headers: Headers,
12+
}
13+
14+
impl Trailers {
15+
/// Create a new instance of `Trailers`.
16+
pub fn new() -> Self {
17+
Self {
18+
headers: Headers::new(),
19+
}
20+
}
21+
22+
/// Insert a header into the headers.
23+
pub fn insert(
24+
&mut self,
25+
name: HeaderName,
26+
values: impl ToHeaderValues,
27+
) -> io::Result<Option<Vec<HeaderValue>>> {
28+
self.headers.insert(name, values)
29+
}
30+
31+
/// Append a header to the headers.
32+
///
33+
/// Unlike `insert` this function will not override the contents of a header, but insert a
34+
/// header if there aren't any. Or else append to the existing list of headers.
35+
pub fn append(&mut self, name: HeaderName, values: impl ToHeaderValues) -> io::Result<()> {
36+
self.headers.append(name, values)
37+
}
38+
39+
/// Get a reference to a header.
40+
pub fn get(&self, name: &HeaderName) -> Option<&Vec<HeaderValue>> {
41+
self.headers.get(name)
42+
}
43+
44+
/// Get a mutable reference to a header.
45+
pub fn get_mut(&mut self, name: &HeaderName) -> Option<&mut Vec<HeaderValue>> {
46+
self.headers.get_mut(name)
47+
}
48+
49+
/// Remove a header.
50+
pub fn remove(&mut self, name: &HeaderName) -> Option<Vec<HeaderValue>> {
51+
self.headers.remove(name)
52+
}
53+
54+
/// An iterator visiting all header pairs in arbitrary order.
55+
pub fn iter<'a>(&'a self) -> Iter<'a> {
56+
self.headers.iter()
57+
}
58+
59+
/// An iterator visiting all header pairs in arbitrary order, with mutable references to the
60+
/// values.
61+
pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a> {
62+
self.headers.iter_mut()
63+
}
64+
65+
/// An iterator visiting all header names in arbitrary order.
66+
pub fn names<'a>(&'a self) -> Names<'a> {
67+
self.headers.names()
68+
}
69+
70+
/// An iterator visiting all header values in arbitrary order.
71+
pub fn values<'a>(&'a self) -> Values<'a> {
72+
self.headers.values()
73+
}
74+
}
75+
76+
impl Clone for Trailers {
77+
fn clone(&self) -> Self {
78+
Self {
79+
headers: Headers {
80+
headers: self.headers.headers.clone(),
81+
},
82+
}
83+
}
84+
}
85+
86+
impl Deref for Trailers {
87+
type Target = Headers;
88+
89+
fn deref(&self) -> &Self::Target {
90+
&self.headers
91+
}
92+
}
93+
94+
impl DerefMut for Trailers {
95+
fn deref_mut(&mut self) -> &mut Self::Target {
96+
&mut self.headers
97+
}
98+
}

0 commit comments

Comments
 (0)