Skip to content

Commit 5d042d5

Browse files
authored
Merge pull request #257 from H1rono/fix-parse-request
`ParseRequestInner`修正
2 parents ebd08be + b7dedfc commit 5d042d5

File tree

1 file changed

+116
-21
lines changed

1 file changed

+116
-21
lines changed

src/parser/http.rs

+116-21
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ use futures::future::Ready;
99
use futures::ready;
1010
use http_body::Body;
1111
use http_body_util::{combinators::Collect, Collected};
12+
use pin_project_lite::pin_project;
1213

1314
use crate::error::{Error, Result};
1415
use crate::events::{Event, EventKind};
1516
use crate::parser::RequestParser;
1617

17-
pin_project_lite::pin_project! {
18+
pin_project! {
1819
#[must_use]
1920
#[project = CollectBodyProject]
2021
struct CollectBody<B>
@@ -44,41 +45,127 @@ where
4445
}
4546
}
4647

47-
pin_project_lite::pin_project! {
48+
pin_project! {
4849
#[must_use]
49-
#[project = ParseRequestInnerProject]
50-
struct ParseRequestInner<K, B> {
51-
#[pin]
52-
kind: K,
50+
#[project = ParseEventKindProject]
51+
struct ParseEventKind<K, B> {
5352
#[pin]
54-
body: B,
53+
inner: K,
54+
body: Option<B>
5555
}
5656
}
5757

58-
impl<K, B> Future for ParseRequestInner<K, B>
58+
impl<K, B> Future for ParseEventKind<K, B>
5959
where
6060
K: Future<Output = Result<EventKind>>,
61+
{
62+
type Output = ParseRequestInner<K, B>;
63+
64+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
65+
let s = self.project();
66+
let res = ready!(s.inner.poll(cx));
67+
let next = match res {
68+
Ok(kind) => {
69+
let body = s.body.take().expect("polled after ready");
70+
ParseRequestInner::ParseBody {
71+
inner: ParseBody { kind, inner: body },
72+
}
73+
}
74+
Err(e) => ParseRequestInner::ParseEventKindFailed {
75+
inner: futures::future::ready(Err(e)),
76+
},
77+
};
78+
Poll::Ready(next)
79+
}
80+
}
81+
82+
type ParseEventKindFailed = Ready<Result<Event>>;
83+
84+
pin_project! {
85+
#[must_use]
86+
#[project = ParseBodyProject]
87+
struct ParseBody<B> {
88+
kind: EventKind,
89+
#[pin]
90+
inner: B,
91+
}
92+
}
93+
94+
impl<B> Future for ParseBody<B>
95+
where
6196
B: Future<Output = Result<Bytes>>,
6297
{
6398
type Output = Result<Event>;
6499

65100
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
66101
let s = self.project();
67-
let kind = match ready!(s.kind.poll(cx)) {
68-
Ok(k) => k,
69-
Err(e) => return Poll::Ready(Err(e)),
70-
};
71-
let body = ready!(s.body.poll(cx));
102+
let body = ready!(s.inner.poll(cx));
72103
let res: Result<Event> = {
73104
let body = body?;
74105
let body = std::str::from_utf8(&body).map_err(Error::read_body_failed)?;
75-
super::parse_body(kind, body)
106+
super::parse_body(*s.kind, body)
76107
};
77108
Poll::Ready(res)
78109
}
79110
}
80111

81-
pin_project_lite::pin_project! {
112+
pin_project! {
113+
#[must_use]
114+
#[project = ParseRequestInnerProject]
115+
#[project_replace = ParseRequestInnerProjectReplace]
116+
enum ParseRequestInner<K, B> {
117+
ParseEventKind {
118+
#[pin]
119+
inner: ParseEventKind<K, B>,
120+
},
121+
ParseEventKindFailed {
122+
#[pin]
123+
inner: ParseEventKindFailed,
124+
},
125+
ParseBody {
126+
#[pin]
127+
inner: ParseBody<B>,
128+
}
129+
}
130+
}
131+
132+
impl<K, B> ParseRequestInner<K, B>
133+
where
134+
K: Future<Output = Result<EventKind>>,
135+
B: Future<Output = Result<Bytes>>,
136+
{
137+
fn new(kind: K, body: B) -> Self {
138+
Self::ParseEventKind {
139+
inner: ParseEventKind {
140+
inner: kind,
141+
body: Some(body),
142+
},
143+
}
144+
}
145+
}
146+
147+
impl<K, B> Future for ParseRequestInner<K, B>
148+
where
149+
K: Future<Output = Result<EventKind>>,
150+
B: Future<Output = Result<Bytes>>,
151+
{
152+
type Output = Result<Event>;
153+
154+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
155+
use ParseRequestInnerProject::{ParseBody, ParseEventKind, ParseEventKindFailed};
156+
let s = self.as_mut().project();
157+
let next = match s {
158+
ParseEventKind { inner } => ready!(inner.poll(cx)),
159+
ParseEventKindFailed { inner } => return inner.poll(cx),
160+
ParseBody { inner } => return inner.poll(cx),
161+
};
162+
self.project_replace(next);
163+
cx.waker().wake_by_ref();
164+
Poll::Pending
165+
}
166+
}
167+
168+
pin_project! {
82169
/// <code>impl [Future]<Output = Result<[Event], [Error]>></code>
83170
///
84171
/// [Future]: std::future::Future
@@ -98,17 +185,16 @@ pin_project_lite::pin_project! {
98185
impl<B> ParseRequest<B>
99186
where
100187
B: Body,
188+
B::Error: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
101189
{
102190
fn new(kind: Result<EventKind>, body: B) -> Self {
103191
use http_body_util::BodyExt;
104192

105193
let kind = futures::future::ready(kind);
106-
let inner = ParseRequestInner {
107-
kind,
108-
body: CollectBody {
109-
collect: body.collect(),
110-
},
194+
let body = CollectBody {
195+
collect: body.collect(),
111196
};
197+
let inner = ParseRequestInner::new(kind, body);
112198
Self { inner }
113199
}
114200
}
@@ -187,7 +273,7 @@ mod tests {
187273
use http_body_util::BodyExt;
188274

189275
use super::{CollectBody, ParseRequest};
190-
use crate::{Event, EventKind};
276+
use crate::{Error, ErrorKind, Event, EventKind};
191277

192278
#[test]
193279
fn collect_body() {
@@ -208,4 +294,13 @@ mod tests {
208294
let event = block_on(fut).unwrap();
209295
assert!(matches!(event, Event::Ping(_)));
210296
}
297+
298+
#[test]
299+
fn parse_event_failed() {
300+
let err: Error = ErrorKind::BotTokenMismatch.into();
301+
let body = String::new();
302+
let fut = ParseRequest::new(Err(err), body);
303+
let err = block_on(fut).unwrap_err();
304+
assert_eq!(err.kind(), ErrorKind::BotTokenMismatch);
305+
}
211306
}

0 commit comments

Comments
 (0)