|
1 | 1 | use futures::sync::mpsc;
|
2 |
| -use futures::{Poll, Stream}; |
| 2 | +use futures::{Async, Poll, Stream}; |
3 | 3 | use postgres_protocol::message::backend::Message;
|
4 |
| -use state_machine_future::{transition, RentToOwn, StateMachineFuture}; |
| 4 | +use std::mem; |
5 | 5 |
|
6 | 6 | use crate::proto::client::{Client, PendingRequest};
|
7 |
| -use crate::Error; |
| 7 | +use crate::{Error, StringRow}; |
8 | 8 |
|
9 |
| -#[derive(StateMachineFuture)] |
10 |
| -pub enum SimpleQuery { |
11 |
| - #[state_machine_future(start, transitions(ReadResponse))] |
| 9 | +pub enum State { |
12 | 10 | Start {
|
13 | 11 | client: Client,
|
14 | 12 | request: PendingRequest,
|
15 | 13 | },
|
16 |
| - #[state_machine_future(transitions(Finished))] |
17 |
| - ReadResponse { receiver: mpsc::Receiver<Message> }, |
18 |
| - #[state_machine_future(ready)] |
19 |
| - Finished(()), |
20 |
| - #[state_machine_future(error)] |
21 |
| - Failed(Error), |
| 14 | + ReadResponse { |
| 15 | + receiver: mpsc::Receiver<Message>, |
| 16 | + }, |
| 17 | + Done, |
22 | 18 | }
|
23 | 19 |
|
24 |
| -impl PollSimpleQuery for SimpleQuery { |
25 |
| - fn poll_start<'a>(state: &'a mut RentToOwn<'a, Start>) -> Poll<AfterStart, Error> { |
26 |
| - let state = state.take(); |
27 |
| - let receiver = state.client.send(state.request)?; |
| 20 | +pub struct SimpleQueryStream(State); |
28 | 21 |
|
29 |
| - transition!(ReadResponse { receiver }) |
30 |
| - } |
| 22 | +impl Stream for SimpleQueryStream { |
| 23 | + type Item = StringRow; |
| 24 | + type Error = Error; |
31 | 25 |
|
32 |
| - fn poll_read_response<'a>( |
33 |
| - state: &'a mut RentToOwn<'a, ReadResponse>, |
34 |
| - ) -> Poll<AfterReadResponse, Error> { |
| 26 | + fn poll(&mut self) -> Poll<Option<StringRow>, Error> { |
35 | 27 | loop {
|
36 |
| - let message = try_ready_receive!(state.receiver.poll()); |
| 28 | + match mem::replace(&mut self.0, State::Done) { |
| 29 | + State::Start { client, request } => { |
| 30 | + let receiver = client.send(request)?; |
| 31 | + self.0 = State::ReadResponse { receiver }; |
| 32 | + } |
| 33 | + State::ReadResponse { mut receiver } => { |
| 34 | + let message = match receiver.poll() { |
| 35 | + Ok(Async::Ready(message)) => message, |
| 36 | + Ok(Async::NotReady) => { |
| 37 | + self.0 = State::ReadResponse { receiver }; |
| 38 | + return Ok(Async::NotReady); |
| 39 | + } |
| 40 | + Err(()) => unreachable!("mpsc receiver can't panic"), |
| 41 | + }; |
37 | 42 |
|
38 |
| - match message { |
39 |
| - Some(Message::CommandComplete(_)) |
40 |
| - | Some(Message::RowDescription(_)) |
41 |
| - | Some(Message::DataRow(_)) |
42 |
| - | Some(Message::EmptyQueryResponse) => {} |
43 |
| - Some(Message::ErrorResponse(body)) => return Err(Error::db(body)), |
44 |
| - Some(Message::ReadyForQuery(_)) => transition!(Finished(())), |
45 |
| - Some(_) => return Err(Error::unexpected_message()), |
46 |
| - None => return Err(Error::closed()), |
| 43 | + match message { |
| 44 | + Some(Message::CommandComplete(_)) |
| 45 | + | Some(Message::RowDescription(_)) |
| 46 | + | Some(Message::EmptyQueryResponse) => { |
| 47 | + self.0 = State::ReadResponse { receiver }; |
| 48 | + } |
| 49 | + Some(Message::DataRow(body)) => { |
| 50 | + self.0 = State::ReadResponse { receiver }; |
| 51 | + let row = StringRow::new(body)?; |
| 52 | + return Ok(Async::Ready(Some(row))); |
| 53 | + } |
| 54 | + Some(Message::ErrorResponse(body)) => return Err(Error::db(body)), |
| 55 | + Some(Message::ReadyForQuery(_)) => return Ok(Async::Ready(None)), |
| 56 | + Some(_) => return Err(Error::unexpected_message()), |
| 57 | + None => return Err(Error::closed()), |
| 58 | + } |
| 59 | + } |
| 60 | + State::Done => return Ok(Async::Ready(None)), |
47 | 61 | }
|
48 | 62 | }
|
49 | 63 | }
|
50 | 64 | }
|
51 | 65 |
|
52 |
| -impl SimpleQueryFuture { |
53 |
| - pub fn new(client: Client, request: PendingRequest) -> SimpleQueryFuture { |
54 |
| - SimpleQuery::start(client, request) |
| 66 | +impl SimpleQueryStream { |
| 67 | + pub fn new(client: Client, request: PendingRequest) -> SimpleQueryStream { |
| 68 | + SimpleQueryStream(State::Start { client, request }) |
55 | 69 | }
|
56 | 70 | }
|
0 commit comments