#async-io #future #traits #poll #associated #kitten-iterator

associated-async-io

使用 futures 而不是 poll 的异步 IO 特性

2 个稳定版本

1.0.1 2019 年 6 月 28 日

#1759 in 异步

MIT/Apache

12KB

associate-async-io

crates.io version build status downloads docs.rs docs

使用 futures 而不是 poll 的异步 IO 特性。这是一个实验,看看是否可以使用 async fn 实现 futures::io 特性。

为什么存在这个项目?

这个项目很有用,因为目前实现 AsyncReadAsyncWriteStream 需要了解 PollPin 和任意自类型。我们认为,如果不需要这些概念就可以实现这些特性,那么这将是一个很好的改进。

pub trait AsyncRead {
    async fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>;
}

pub trait AsyncWrite {
    async fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
}

pub trait AsyncIterator {
    type Item;
    async fn next(&mut self) -> Option<Self::Item>;
}

这些将直接对应于 ReadWriteIterator

pub trait AsyncRead {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>;
}

pub trait AsyncWrite {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
}

pub trait AsyncIterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
}

然而,目前特性中的 async fn 并不工作。因此,我们使用关联类型定义这些特性。

pub trait AsyncRead {
    type Fut: Future<Output = io::Result<usize>>;
    fn read(&mut self, buf: &mut [u8]) -> Self::Fut;
}

pub trait AsyncWrite {
    type Fut: Future<Output = io::Result<usize>>;
    fn write(&mut self, buf: &[u8]) -> Self::Fut;
}

pub trait AsyncIterator {
    type Item;
    type Fut: Future<Output = Option<Self::Item>>;
    fn next(&mut self) -> Self::Fut;
}

由于编译器的原因,这意味着目前存在额外的开销,因为需要额外的 box。但我们认为这是可以接受的,因为它不太可能成为瓶颈,并且这将是临时的。

然而,一个限制是,它不能返回借用值,因为它依赖于 GATs。这似乎是使用这些特性今天最令人信服的反论点。

示例

#![feature(async_await)]

use futures::executor::block_on;
use associated_async_io::AsyncIterator;
use futures::future::{self, Future};
use std::pin::Pin;

#[derive(Debug)]
struct KittenIterator {
    cursor: usize,
    kittens: Vec<String>,
}

impl KittenIterator {
    fn new(mut kittens: Vec<String>) -> Self {
        kittens.reverse();
        Self { cursor: 0, kittens }
    }
}

impl AsyncIterator for KittenIterator {
    type Item = String;
    type Fut = Pin<Box<Future<Output = Option<Self::Item>>>>;
    fn next(&mut self) -> Self::Fut {
        self.cursor += 1;
        let kitten = self.kittens.pop();
        Box::pin(future::ready(kitten))
    }
}

fn main () {
    block_on(async {
        let kittens = vec!["chashu".to_owned(), "nori".to_owned()];
        let mut kittens = KittenIterator::new(kittens);
        AsyncIterator::next(&mut kittens);
    })
}

安装

$ cargo add associate-async-io

安全性

此 crate 使用 #![deny(unsafe_code)] 确保所有内容都在 100% 安全的 Rust 中实现。

贡献

想加入我们?查看我们的 "贡献" 指南 并查看一些这些问题

参考

无。

许可证

MITApache-2.0

无运行时依赖