Error handling 如何使用问号运算符处理东京期货的错误?

Error handling 如何使用问号运算符处理东京期货的错误?,error-handling,rust,future,rust-tokio,Error Handling,Rust,Future,Rust Tokio,我有一个客户处理一个未来,做一些事情。是否可以使用impl Future作为返回类型并进行更好的错误处理 pub fn handle_client(client: Client) -> impl Future<Item = (), Error = io::Error> { let magic = client.header.magic; let stream_client = TcpStream::connect(&client.addr).and_th

我有一个客户处理一个
未来
,做一些事情。是否可以使用
impl Future
作为返回类型并进行更好的错误处理

pub fn handle_client(client: Client) -> impl Future<Item = (), Error = io::Error> {
    let magic = client.header.magic;
    let stream_client = TcpStream::connect(&client.addr).and_then(|stream| {
        let addr: Vec<u8> = serialize_addr(stream.local_addr()?, magic)?;
        write_all(stream, addr).then(|result| {
            // some code
            Ok(())
        })
    });
    stream_client
}
我制作了链接映射,然后进行错误处理,但问题是我不知道如何在final
中获得
TcpStream
。然后
闭包。我唯一找到的
TcpStream
位置是WriteAll结构内部,但它是私有的。此外,write_都消耗流

use futures::Future;
use std::{io, net::SocketAddr};
use tokio::{
    io::{write_all, AsyncRead, AsyncWrite},
    net::TcpStream,
};

type Error = Box<dyn std::error::Error>;

fn serialize_addr(addr: SocketAddr) -> Result<Vec<u8>, Error> {
    Ok(vec![])
}

fn handle_client(addr: &SocketAddr) -> impl Future<Item = (), Error = Error> {
    TcpStream::connect(addr)
        .map_err(Into::into)
        .and_then(|stream| stream.local_addr().map(|stream_addr| (stream, stream_addr)))
        .map_err(Into::into)
        .and_then(|(stream, stream_addr)| serialize_addr(stream_addr).map(|info| (stream, info)))
        .map(|(stream, info)| write_all(stream, info))
        .then(|result| {
            let result = result.unwrap();
            let stream = match result.state {
                Writing { a } => a,
                _ => panic!("cannot get stream"),
            };
            // some code
            Ok(())
        })
}

fn main() {
    let addr = "127.0.0.1:8900".parse().unwrap();
    handle_client(&addr);
}
使用期货::未来;
使用std::{io,net::SocketAddr};
使用东京:{
io::{write_all,AsyncRead,AsyncWrite},
net::TcpStream,
};
类型错误=框;
fn serialize_addr(addr:SocketAddr)->结果{
好的(vec![])
}
fn handle_client(地址:&SocketAddr)->impl Future{
TcpStream::connect(地址)
.map_err(Into::Into)
。然后(| stream | stream.local_addr().map(| stream_addr |(stream,stream_addr)))
.map_err(Into::Into)
然后(|(流,流地址)|序列化|地址(流地址).map(|信息|(流,信息)))
.map(|(流,信息)|写入所有(流,信息))
.然后(|结果|{
让result=result.unwrap();
让流=匹配结果.state{
写入{a}=>a,
_=>恐慌!(“无法获取流”),
};
//一些代码
好(())
})
}
fn main(){
让addr=“127.0.0.1:8900”。parse().unwrap();
处理客户和地址;
}

TL;DR:您没有使用
操作符


由于您没有提供一个,以下是您的问题。请注意,我们不知道您的
serialize\u addr
函数的错误类型是什么,因此我必须选择以下内容:

use futures::Future;
use std::{io, net::SocketAddr};
use tokio::{io::write_all, net::TcpStream};

fn serialize_addr() -> Result<Vec<u8>, Box<dyn std::error::Error>> {
    Ok(vec![])
}

pub fn handle_client(addr: &SocketAddr) -> impl Future<Item = (), Error = io::Error> {
    TcpStream::connect(addr).and_then(|stream| {
        let addr = serialize_addr()?;
        write_all(stream, addr).then(|_result| Ok(()))
    })
}

将来,
async
/
await
语法将使这一点更容易理解。

两个流的解决方案:

fn handle_client(addr: &SocketAddr) -> impl Future<Item = (), Error = Error> {
    TcpStream::connect(addr)
        .map_err(Into::into)
        .and_then(|remote_stream| {
            remote_stream
                .local_addr()
                .map(|remote_addr| (remote_stream, remote_addr))
        })
        .map_err(Into::into)
        .and_then(|(remote_stream, remote_addr)| {
            TcpStream::connect(&"".parse().unwrap())
                .map(move |proxy_stream| (remote_stream, proxy_stream, remote_addr))
        })
        .and_then(|(remote_stream, proxy_stream, remote_addr)| {
            serialize_addr(remote_addr)
                .map(|info| (remote_stream, proxy_stream, info))
                .map_err(|_| io::Error::from(io::ErrorKind::AddrNotAvailable))
        })
        .and_then(|(remote_stream, proxy_stream, info)| {
            write_all(proxy_stream, info).map(|proxy_stream| (remote_stream, proxy_stream.0))
        })
        .and_then(|(remote_stream, proxy_stream)| {
            // working with streams
        })
        .then(|_result| Ok(()))
}
fn handle\u client(addr:&SocketAddr)->impl Future{
TcpStream::connect(地址)
.map_err(Into::Into)
.然后(|远程|流|{
远程流
.local_addr()
.map(| remote_addr |(remote_stream,remote_addr))
})
.map_err(Into::Into)
。然后(|(远程流,远程地址)|{
TcpStream::connect(&“.parse().unwrap())
.map(移动|代理|流|(远程|流、代理|流、远程|地址))
})
。然后(|(远程|流、代理|流、远程|地址)|{
序列化地址(远程地址)
.map(|info |(远程_流、代理_流、信息))
.map_err(| | io::Error::from(io::ErrorKind::AddrNotAvailable))
})
。然后(|(远程|流、代理|流、信息)|{
write_all(proxy_stream,info).map(| proxy_stream |(remote_stream,proxy_stream.0))
})
。然后(|(远程|流,代理|流)|{
//处理流
})
.然后(| |结果|好(()))
}

例如,您的代码使用了我们不知道其签名的未定义类型和方法。您的错误消息甚至与代码不对应。当下面的代码使用
和_then
时,您为什么要使用
映射(…全部写入)
?您不能随意更改您调用的方法并期望它工作。当使用
和_then
时,未来的成功价值是
(TcpStream,Vec)
。我不知道为什么,但不强制转换为
序列化地址(远程地址)。映射错误(| | io::Error::from(io::ErrorKind::AddrNotAvailable))
我无法使用
。然后
而不是
.map
fn handle_client(addr: &SocketAddr) -> impl Future<Item = (), Error = Error> {
    TcpStream::connect(addr)
        .map_err(Into::into)
        .and_then(|remote_stream| {
            remote_stream
                .local_addr()
                .map(|remote_addr| (remote_stream, remote_addr))
        })
        .map_err(Into::into)
        .and_then(|(remote_stream, remote_addr)| {
            TcpStream::connect(&"".parse().unwrap())
                .map(move |proxy_stream| (remote_stream, proxy_stream, remote_addr))
        })
        .and_then(|(remote_stream, proxy_stream, remote_addr)| {
            serialize_addr(remote_addr)
                .map(|info| (remote_stream, proxy_stream, info))
                .map_err(|_| io::Error::from(io::ErrorKind::AddrNotAvailable))
        })
        .and_then(|(remote_stream, proxy_stream, info)| {
            write_all(proxy_stream, info).map(|proxy_stream| (remote_stream, proxy_stream.0))
        })
        .and_then(|(remote_stream, proxy_stream)| {
            // working with streams
        })
        .then(|_result| Ok(()))
}