Rust 我如何分割、去抖动和加入流?
我正在努力理解Rust 我如何分割、去抖动和加入流?,rust,stream,Rust,Stream,我正在努力理解futures::streams周围的基础架构 假设我有一个u8项流。我想将其转换为事件项流,其中: enum事件{ 短(u8), 长(u8), } 每当底层流发出x时,我的结果流应该发出Event::Short(x)。只要底层流在N秒内未更改其x值,它也应发出Event::Long(x) 概念性步骤将是: 将流拆分为流a和b 在流b上应用去抖动,使其仅在x在N秒内未更改时发出x 把这两条小溪连接起来 我相信join将由我们来处理。但是,如果原始流的项目是Copy,如何将其拆分为
futures::streams
周围的基础架构
假设我有一个u8
项流。我想将其转换为事件
项流,其中:
enum事件{
短(u8),
长(u8),
}
每当底层流发出x
时,我的结果流应该发出Event::Short(x)
。只要底层流在N
秒内未更改其x
值,它也应发出Event::Long(x)
概念性步骤将是:
a
和b
b
上应用去抖动,使其仅在x
在N
秒内未更改时发出x
我相信join将由我们来处理。但是,如果原始流的项目是
Copy
,如何将其拆分为两个呢?在期货
或东京
中是否有像去抖动机制这样的实用工具?它可能并不完全是你想要的,但它确实符合你的要求
use {
futures::{
prelude::*,
Async, Poll,
stream::{
Stream, Fuse,
},
sync::mpsc,
},
std::{
thread,
time::{Duration, Instant},
}
};
#[derive(Debug)]
enum Event<T> {
Short(T),
Long(T),
}
#[derive(Debug)]
struct Debounce<S: Stream> {
stream: Fuse<S>,
debouncetime: Duration,
timestamp: Instant,
last: S::Item,
emitted: bool,
}
impl<S> Debounce<S>
where S: Stream, S::Item: Copy + Default + PartialEq {
fn new(s: S) -> Self {
Self{
stream: s.fuse(),
debouncetime: Duration::from_millis(2300),
timestamp: Instant::now(),
last: Default::default(),
emitted: true,
}
}
}
impl<S> Stream for Debounce<S>
where S: Stream, S::Item: Copy + Default + PartialEq
{
type Item = Event<S::Item>;
type Error = S::Error;
fn poll(&mut self) -> Poll<Option<Event<S::Item>>, S::Error> {
if !self.emitted && self.timestamp.elapsed() >= self.debouncetime {
self.emitted = true;
return Ok(Some(Event::Long(self.last)).into())
}
match self.stream.poll()? {
Async::Ready(Some(item)) => {
if item != self.last {
self.last = item;
self.timestamp = Instant::now();
self.emitted = false;
}
Ok(Some(Event::Short(item)).into())
}
Async::Ready(None) => Ok(None.into()),
Async::NotReady => Ok(Async::NotReady)
}
}
}
fn main() {
let (mut tx, rx) = mpsc::channel(1);
thread::spawn(move || {
for i in vec![1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 7] {
tx = tx.send(i).wait().unwrap();
thread::sleep(Duration::from_secs(1));
}
});
let result = Debounce::new(rx).collect().wait();
dbg!(result.unwrap());
}
使用{
期货::{
序曲::*,
异步,轮询,
溪流::{
流,熔丝,
},
同步::mpsc,
},
标准::{
线
时间::{Duration,Instant},
}
};
#[导出(调试)]
枚举事件{
短(T),
长(T),
}
#[导出(调试)]
结构去盎司{
流:引信,
去BounceTime:持续时间,
时间戳:即时,
最后:S::项,
他说:布尔,
}
冲击去盎司
其中S:Stream,S::Item:Copy+Default+PartialEq{
fn新(s:s)->自我{
自我{
流:s.fuse(),
去BounceTime:持续时间::从_millis(2300),
时间戳:Instant::now(),
last:Default::Default(),
对,,
}
}
}
用于去盎司的impl流
其中S:Stream,S::Item:Copy+Default+PartialEq
{
类型项目=事件;
类型Error=S::Error;
fn轮询(&mut self)->轮询{
如果!self.emissed&&self.timestamp.appeased()>=self.debouncetime{
self.emissed=true;
返回Ok(Some(Event::Long(self.last)).into())
}
匹配self.stream.poll(){
Async::Ready(部分(项目))=>{
如果项目!=self.last{
self.last=项目;
self.timestamp=Instant::now();
自发光=假;
}
Ok(一些(事件::短(项)).into())
}
Async::Ready(None)=>Ok(None.into()),
Async::NotReady=>Ok(Async::NotReady)
}
}
}
fn main(){
let(mut-tx,rx)=mpsc::信道(1);
线程::生成(移动| |{
对于vec中的i![1,2,3,3,4,4,5,5,6,7]{
tx=tx.send(i).wait().unwrap();
线程::睡眠(持续时间::从秒(1));
}
});
让结果=Debounce::new(rx).collect().wait();
dbg!(result.unwrap());
}
这确实非常接近。这肯定能帮我弄清楚事情到底是怎么回事,谢谢!我希望看到一个使用组合函数的答案,但我觉得impl-Stream
将是解决方案。