8 个版本
使用旧的 Rust 2015
0.0.8 | 2015年10月10日 |
---|---|
0.0.7 | 2015年10月10日 |
#4 in #conduit
24KB
392 行
rust-plumbum
Rust 的类似管道的数据处理库
lib.rs
:
Plumbum(拉丁语意为铅)是 Michael Snoyman 的优秀库 conduit
的移植。
它允许在常量内存中生产、转换和消费数据流。它可以用于处理文件、处理网络接口或以事件驱动的方式解析结构化数据。
特性
-
可以处理大型且可能无限的数据流,而不会占用大量内存。
-
数据块是懒加载的,一次处理一个,而不是需要一次性读取整个主体。
-
结果组件是纯计算,允许我们在处理 I/O 的命令式世界中保持可组合性。
基础
有三个主要概念
Source
将生成数据流并将其发送到下游。Sink
将从上游消费数据流并生成返回值。Conduit
将从上游消费数据流并生成一个新的数据流以发送到下游。
为了组合这些不同的组件,我们使用了连接和融合。 connect
方法将 Source
和 Sink
结合起来,将前者产生的值喂入后者,并产生最终结果。另一方面,融合将两个组件结合起来生成一个新的组件。例如,将 Conduit
和 Sink
融合到一个新的 Sink
中,将消费与原始 Conduit
相同的值,并产生与原始 Sink
相同的结果。
原语
有四个核心原语
consume
从上游获取单个值(如果可用)。produce
向下游发送单个值。leftover
将单个值放回上游队列,以便在下一次调用consume
时读取。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):...")
}