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
    将是解决方案。