铁锈期货 - 一起加入两个期货

时间:2017-10-04 16:05:02

标签: rust

我有这段代码

use futures::Map;
use futures::sink::SendAll;
use futures::sink::SinkFromErr;
use futures::stream::Forward;
use futures::sync::mpsc::Receiver;
use futures::sync::mpsc::Sender;
use futures::{Future, Stream, Sink};
use std::boxed::FnBox;
use tokio_core::reactor::Core;
use websocket::async::futures::stream::SplitSink;
use websocket::async::futures::stream::SplitStream;
use websocket::ClientBuilder;
use websocket;

pub fn main(recv: Receiver<String>, send: Sender<websocket::OwnedMessage>) -> Box<FnBox() -> () + Send> {
    Box::new(move || {
        let mut core = Core::new().unwrap();
        let handle = core.handle();

        let f = ClientBuilder::new("wss://...")
            .unwrap()
            .async_connect(None, &handle)
            .from_err::<Error>()
            .map(|(duplex, _)| duplex.split())
            .and_then(|(sink, stream): (SplitSink<_>, SplitStream<_>)| {

                let writer: Map<SendAll<SinkFromErr<SplitSink<_>, _>, _>, _> =
                    sink
                    .sink_from_err()
                    .send_all(recv.map(websocket::OwnedMessage::Text).map_err(Error::Receiver))
                    .map(|_| ());

                // Trying to uncomment these lines:
                // let reader =
                //     stream
                //     .forward(send);
                //
                // reader.join(writer)

                // Comment this out:
                writer
            });

        core.run(f).expect("Unable to run");
    })
}

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        WebSocket(err: websocket::WebSocketError) {
            from()
            description("websocket error")
            display("WebSocket error: {}", err)
            cause(err)
        }
        Receiver(err: ()) {
            description("receiver error")
            display("Receiver error")
        }
    }
}

为了清晰起见,我添加了一些类型注释。这个版本编译,但我想要另一个未来,从流(stream)读取并写入send。我不能让它编译,我输入错误是完全不可理解的。所以我的问题是:

  1. 如何使forward()调用编译? (尝试启用已注释掉的代码)
  2. 你是如何提出编译的代码的?根据我的经验,期货繁重的代码无法编写和理解,因为类型太复杂,类型错误也难以理解。

1 个答案:

答案 0 :(得分:1)

我需要两个map_err个调用,一个用于映射来自stream的websocket错误,一个用于映射来自send的发件人错误:

pub fn main(recv: Receiver<String>, send: Sender<websocket::OwnedMessage>) -> Box<FnBox() -> () + Send> {
    Box::new(move || {
        let mut core = Core::new().unwrap();
        let handle = core.handle();

        let f = ClientBuilder::new("wss://...")
            .unwrap()
            .async_connect(None, &handle)
            .from_err::<Error>()
            .map(|(duplex, _)| duplex.split())
            .and_then(|(sink, stream): (SplitSink<_>, SplitStream<_>)| {

                let writer: Map<SendAll<SinkFromErr<SplitSink<_>, _>, _>, _> =
                    sink
                    .sink_from_err()
                    .send_all(recv.map(websocket::OwnedMessage::Text).map_err(Error::Receiver))
                    .map(|_| ());

                let reader =
                    stream
                    .map_err(Error::WebSocket)
                    .forward(send.sink_map_err(Error::Sender));

                reader.join(writer)
            });

        core.run(f).expect("Unable to run");
    })
}