8 个版本

使用旧的 Rust 2015

0.0.8 2015年10月10日
0.0.7 2015年10月10日

#4 in #conduit

MIT 许可证

24KB
392

rust-plumbum

Rust 的类似管道的数据处理库


lib.rs:

Plumbum(拉丁语意为铅)是 Michael Snoyman 的优秀库 conduit 的移植。

它允许在常量内存中生产、转换和消费数据流。它可以用于处理文件、处理网络接口或以事件驱动的方式解析结构化数据。

特性

  • 可以处理大型且可能无限的数据流,而不会占用大量内存。

  • 数据块是懒加载的,一次处理一个,而不是需要一次性读取整个主体。

  • 结果组件是纯计算,允许我们在处理 I/O 的命令式世界中保持可组合性。

基础

有三个主要概念

  1. Source 将生成数据流并将其发送到下游。
  2. Sink 将从上游消费数据流并生成返回值。
  3. Conduit 将从上游消费数据流并生成一个新的数据流以发送到下游。

为了组合这些不同的组件,我们使用了连接和融合。 connect 方法将 SourceSink 结合起来,将前者产生的值喂入后者,并产生最终结果。另一方面,融合将两个组件结合起来生成一个新的组件。例如,将 ConduitSink 融合到一个新的 Sink 中,将消费与原始 Conduit 相同的值,并产生与原始 Sink 相同的结果。

原语

有四个核心原语

  1. consume 从上游获取单个值(如果可用)。
  2. produce 向下游发送单个值。
  3. leftover 将单个值放回上游队列,以便在下一次调用 consume 时读取。
  4. defer 引入了一个懒加载点,人为地推迟所有进一步的操作。

示例

use plumbum::*;

fn source<'a>() -> Source<'a, i32> {
    defer()
    .and(produce(1))
    .and(produce(2))
    .and(produce(3))
    .and(produce(4))
}

fn conduit<'a>() -> Conduit<'a, i32, String> {
    // Get adjacent pairs from upstream
    consume().zip(consume()).and_then(|res| {
        match res {
            (Some(i1), Some(i2)) => {
                produce(format!("({},{})", i1, i2))
                .and(leftover(i2))
                .and(conduit())
            },
            _ => ().into()
        }
    })
}

fn sink<'a>() -> Sink<'a, String, String> {
    consume().and_then(|res| {
        match res {
            None => "...".to_string().into(),
            Some(str) => sink().and_then(move |next| {
                format!("{}:{}", str, next).into()
            })
        }
    })
}

fn main() {
    let res = source().fuse(conduit()).connect(sink());
    assert_eq!(res, "(1,2):(2,3):(3,4):...")
}

无运行时依赖