@@ -9,12 +9,13 @@ use futures::future::Ready;
9
9
use futures:: ready;
10
10
use http_body:: Body ;
11
11
use http_body_util:: { combinators:: Collect , Collected } ;
12
+ use pin_project_lite:: pin_project;
12
13
13
14
use crate :: error:: { Error , Result } ;
14
15
use crate :: events:: { Event , EventKind } ;
15
16
use crate :: parser:: RequestParser ;
16
17
17
- pin_project_lite :: pin_project! {
18
+ pin_project ! {
18
19
#[ must_use]
19
20
#[ project = CollectBodyProject ]
20
21
struct CollectBody <B >
@@ -44,41 +45,127 @@ where
44
45
}
45
46
}
46
47
47
- pin_project_lite :: pin_project! {
48
+ pin_project ! {
48
49
#[ must_use]
49
- #[ project = ParseRequestInnerProject ]
50
- struct ParseRequestInner <K , B > {
51
- #[ pin]
52
- kind: K ,
50
+ #[ project = ParseEventKindProject ]
51
+ struct ParseEventKind <K , B > {
53
52
#[ pin]
54
- body: B ,
53
+ inner: K ,
54
+ body: Option <B >
55
55
}
56
56
}
57
57
58
- impl < K , B > Future for ParseRequestInner < K , B >
58
+ impl < K , B > Future for ParseEventKind < K , B >
59
59
where
60
60
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
61
96
B : Future < Output = Result < Bytes > > ,
62
97
{
63
98
type Output = Result < Event > ;
64
99
65
100
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
66
101
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) ) ;
72
103
let res: Result < Event > = {
73
104
let body = body?;
74
105
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)
76
107
} ;
77
108
Poll :: Ready ( res)
78
109
}
79
110
}
80
111
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 ! {
82
169
/// <code>impl [Future]<Output = Result<[Event], [Error]>></code>
83
170
///
84
171
/// [Future]: std::future::Future
@@ -98,17 +185,16 @@ pin_project_lite::pin_project! {
98
185
impl < B > ParseRequest < B >
99
186
where
100
187
B : Body ,
188
+ B :: Error : Into < Box < dyn std:: error:: Error + Send + Sync + ' static > > ,
101
189
{
102
190
fn new ( kind : Result < EventKind > , body : B ) -> Self {
103
191
use http_body_util:: BodyExt ;
104
192
105
193
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 ( ) ,
111
196
} ;
197
+ let inner = ParseRequestInner :: new ( kind, body) ;
112
198
Self { inner }
113
199
}
114
200
}
@@ -187,7 +273,7 @@ mod tests {
187
273
use http_body_util:: BodyExt ;
188
274
189
275
use super :: { CollectBody , ParseRequest } ;
190
- use crate :: { Event , EventKind } ;
276
+ use crate :: { Error , ErrorKind , Event , EventKind } ;
191
277
192
278
#[ test]
193
279
fn collect_body ( ) {
@@ -208,4 +294,13 @@ mod tests {
208
294
let event = block_on ( fut) . unwrap ( ) ;
209
295
assert ! ( matches!( event, Event :: Ping ( _) ) ) ;
210
296
}
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
+ }
211
306
}
0 commit comments