1
1
use bytes:: Bytes ;
2
2
use futures:: { Async , AsyncSink , Future , Poll , Sink , StartSend , Stream } ;
3
3
use futures:: sync:: { mpsc, oneshot} ;
4
+ #[ cfg( feature = "tokio-proto" ) ]
4
5
use tokio_proto;
5
6
use std:: borrow:: Cow ;
6
7
7
8
use super :: Chunk ;
8
9
10
+ #[ cfg( feature = "tokio-proto" ) ]
9
11
pub type TokioBody = tokio_proto:: streaming:: Body < Chunk , :: Error > ;
10
12
pub type BodySender = mpsc:: Sender < Result < Chunk , :: Error > > ;
11
13
@@ -16,33 +18,36 @@ pub struct Body(Inner);
16
18
17
19
#[ derive( Debug ) ]
18
20
enum Inner {
21
+ #[ cfg( feature = "tokio-proto" ) ]
19
22
Tokio ( TokioBody ) ,
20
- Hyper {
21
- close_tx : oneshot:: Sender < ( ) > ,
23
+ Chan {
24
+ close_tx : oneshot:: Sender < bool > ,
22
25
rx : mpsc:: Receiver < Result < Chunk , :: Error > > ,
23
- }
26
+ } ,
27
+ Once ( Option < Chunk > ) ,
28
+ Empty ,
24
29
}
25
30
26
31
//pub(crate)
27
32
#[ derive( Debug ) ]
28
33
pub struct ChunkSender {
29
- close_rx : oneshot:: Receiver < ( ) > ,
34
+ close_rx : oneshot:: Receiver < bool > ,
35
+ close_rx_check : bool ,
30
36
tx : BodySender ,
31
37
}
32
38
33
39
impl Body {
34
40
/// Return an empty body stream
35
41
#[ inline]
36
42
pub fn empty ( ) -> Body {
37
- Body ( Inner :: Tokio ( TokioBody :: empty ( ) ) )
43
+ Body ( Inner :: Empty )
38
44
}
39
45
40
46
/// Return a body stream with an associated sender half
41
47
#[ inline]
42
48
pub fn pair ( ) -> ( mpsc:: Sender < Result < Chunk , :: Error > > , Body ) {
43
- let ( tx, rx) = TokioBody :: pair ( ) ;
44
- let rx = Body ( Inner :: Tokio ( rx) ) ;
45
- ( tx, rx)
49
+ let ( tx, rx) = channel ( ) ;
50
+ ( tx. tx , rx)
46
51
}
47
52
}
48
53
@@ -60,13 +65,16 @@ impl Stream for Body {
60
65
#[ inline]
61
66
fn poll ( & mut self ) -> Poll < Option < Chunk > , :: Error > {
62
67
match self . 0 {
68
+ #[ cfg( feature = "tokio-proto" ) ]
63
69
Inner :: Tokio ( ref mut rx) => rx. poll ( ) ,
64
- Inner :: Hyper { ref mut rx, .. } => match rx. poll ( ) . expect ( "mpsc cannot error" ) {
70
+ Inner :: Chan { ref mut rx, .. } => match rx. poll ( ) . expect ( "mpsc cannot error" ) {
65
71
Async :: Ready ( Some ( Ok ( chunk) ) ) => Ok ( Async :: Ready ( Some ( chunk) ) ) ,
66
72
Async :: Ready ( Some ( Err ( err) ) ) => Err ( err) ,
67
73
Async :: Ready ( None ) => Ok ( Async :: Ready ( None ) ) ,
68
74
Async :: NotReady => Ok ( Async :: NotReady ) ,
69
75
} ,
76
+ Inner :: Once ( ref mut val) => Ok ( Async :: Ready ( val. take ( ) ) ) ,
77
+ Inner :: Empty => Ok ( Async :: Ready ( None ) ) ,
70
78
}
71
79
}
72
80
}
@@ -78,9 +86,10 @@ pub fn channel() -> (ChunkSender, Body) {
78
86
79
87
let tx = ChunkSender {
80
88
close_rx : close_rx,
89
+ close_rx_check : true ,
81
90
tx : tx,
82
91
} ;
83
- let rx = Body ( Inner :: Hyper {
92
+ let rx = Body ( Inner :: Chan {
84
93
close_tx : close_tx,
85
94
rx : rx,
86
95
} ) ;
@@ -90,9 +99,16 @@ pub fn channel() -> (ChunkSender, Body) {
90
99
91
100
impl ChunkSender {
92
101
pub fn poll_ready ( & mut self ) -> Poll < ( ) , ( ) > {
93
- match self . close_rx . poll ( ) {
94
- Ok ( Async :: Ready ( ( ) ) ) | Err ( _) => return Err ( ( ) ) ,
95
- Ok ( Async :: NotReady ) => ( ) ,
102
+ if self . close_rx_check {
103
+ match self . close_rx . poll ( ) {
104
+ Ok ( Async :: Ready ( true ) ) | Err ( _) => return Err ( ( ) ) ,
105
+ Ok ( Async :: Ready ( false ) ) => {
106
+ // needed to allow converting into a plain mpsc::Receiver
107
+ // if it has been, the tx will send false to disable this check
108
+ self . close_rx_check = false ;
109
+ }
110
+ Ok ( Async :: NotReady ) => ( ) ,
111
+ }
96
112
}
97
113
98
114
self . tx . poll_ready ( ) . map_err ( |_| ( ) )
@@ -107,63 +123,67 @@ impl ChunkSender {
107
123
}
108
124
}
109
125
110
- // deprecate soon, but can't really deprecate trait impls
111
- #[ doc( hidden) ]
112
- impl From < Body > for tokio_proto:: streaming:: Body < Chunk , :: Error > {
113
- #[ inline]
114
- fn from ( b : Body ) -> tokio_proto:: streaming:: Body < Chunk , :: Error > {
115
- match b. 0 {
116
- Inner :: Tokio ( b) => b,
117
- Inner :: Hyper { close_tx, rx } => {
118
- warn ! ( "converting hyper::Body into a tokio_proto Body is deprecated" ) ;
119
- :: std:: mem:: forget ( close_tx) ;
120
- rx. into ( )
126
+ feat_server_proto ! {
127
+ impl From <Body > for tokio_proto:: streaming:: Body <Chunk , :: Error > {
128
+ fn from( b: Body ) -> tokio_proto:: streaming:: Body <Chunk , :: Error > {
129
+ match b. 0 {
130
+ Inner :: Tokio ( b) => b,
131
+ Inner :: Chan { close_tx, rx } => {
132
+ // disable knowing if the Rx gets dropped, since we cannot
133
+ // pass this tx along.
134
+ let _ = close_tx. send( false ) ;
135
+ rx. into( )
136
+ } ,
137
+ Inner :: Once ( Some ( chunk) ) => TokioBody :: from( chunk) ,
138
+ Inner :: Once ( None ) |
139
+ Inner :: Empty => TokioBody :: empty( ) ,
121
140
}
122
141
}
123
142
}
124
- }
125
143
126
- // deprecate soon, but can't really deprecate trait impls
127
- #[ doc( hidden) ]
128
- impl From < tokio_proto:: streaming:: Body < Chunk , :: Error > > for Body {
129
- #[ inline]
130
- fn from ( tokio_body : tokio_proto:: streaming:: Body < Chunk , :: Error > ) -> Body {
131
- Body ( Inner :: Tokio ( tokio_body) )
144
+ impl From <tokio_proto:: streaming:: Body <Chunk , :: Error >> for Body {
145
+ fn from( tokio_body: tokio_proto:: streaming:: Body <Chunk , :: Error >) -> Body {
146
+ Body ( Inner :: Tokio ( tokio_body) )
147
+ }
132
148
}
133
149
}
134
150
135
151
impl From < mpsc:: Receiver < Result < Chunk , :: Error > > > for Body {
136
152
#[ inline]
137
153
fn from ( src : mpsc:: Receiver < Result < Chunk , :: Error > > ) -> Body {
138
- TokioBody :: from ( src) . into ( )
154
+ let ( tx, _) = oneshot:: channel ( ) ;
155
+ Body ( Inner :: Chan {
156
+ close_tx : tx,
157
+ rx : src,
158
+ } )
139
159
}
140
160
}
141
161
142
162
impl From < Chunk > for Body {
143
163
#[ inline]
144
164
fn from ( chunk : Chunk ) -> Body {
145
- TokioBody :: from ( chunk) . into ( )
165
+ Body ( Inner :: Once ( Some ( chunk) ) )
146
166
}
147
167
}
148
168
149
169
impl From < Bytes > for Body {
150
170
#[ inline]
151
171
fn from ( bytes : Bytes ) -> Body {
152
- Body :: from ( TokioBody :: from ( Chunk :: from ( bytes) ) )
172
+ Body :: from ( Chunk :: from ( bytes) )
153
173
}
154
174
}
155
175
156
176
impl From < Vec < u8 > > for Body {
157
177
#[ inline]
158
178
fn from ( vec : Vec < u8 > ) -> Body {
159
- Body :: from ( TokioBody :: from ( Chunk :: from ( vec) ) )
179
+ Body :: from ( Chunk :: from ( vec) )
160
180
}
161
181
}
162
182
163
183
impl From < & ' static [ u8 ] > for Body {
164
184
#[ inline]
165
185
fn from ( slice : & ' static [ u8 ] ) -> Body {
166
- Body :: from ( TokioBody :: from ( Chunk :: from ( slice) ) )
186
+ Body :: from ( Chunk :: from ( slice) )
167
187
}
168
188
}
169
189
@@ -180,14 +200,14 @@ impl From<Cow<'static, [u8]>> for Body {
180
200
impl From < String > for Body {
181
201
#[ inline]
182
202
fn from ( s : String ) -> Body {
183
- Body :: from ( TokioBody :: from ( Chunk :: from ( s. into_bytes ( ) ) ) )
203
+ Body :: from ( Chunk :: from ( s. into_bytes ( ) ) )
184
204
}
185
205
}
186
206
187
207
impl From < & ' static str > for Body {
188
208
#[ inline]
189
209
fn from ( slice : & ' static str ) -> Body {
190
- Body :: from ( TokioBody :: from ( Chunk :: from ( slice. as_bytes ( ) ) ) )
210
+ Body :: from ( Chunk :: from ( slice. as_bytes ( ) ) )
191
211
}
192
212
}
193
213
0 commit comments