【Iced】stream.rs文件

rust 复制代码
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};

use futures::stream::Stream;

use crate::subscription::EventStream;

/// 将Stream转换为EventStream
pub fn from_stream<Message, S>(stream: S) -> EventStream<Message>
where
    Message: 'static + Send,
    S: Stream<Item = Message> + Send + 'static,
{
    EventStream::from(Box::pin(stream))
}

/// 将Future转换为EventStream
pub fn from_future<Message, F>(future: F) -> EventStream<Message>
where
    Message: 'static + Send,
    F: Future<Output = Message> + Send + 'static,
{
    from_stream(futures::stream::once(future))
}

/// 将多个EventStream合并为一个
pub fn merge<Message>(streams: Vec<EventStream<Message>>) -> EventStream<Message>
where
    Message: 'static + Send,
{
    if streams.is_empty() {
        return EventStream::from(Box::pin(futures::stream::empty()));
    }

    let mut merged = streams.into_iter().map(Into::into).collect::<Vec<_>>();
    
    EventStream::from(Box::pin(futures::stream::select_all(merged)))
}

/// 创建一个空的EventStream
pub fn empty<Message>() -> EventStream<Message>
where
    Message: 'static + Send,
{
    EventStream::from(Box::pin(futures::stream::empty()))
}

/// 创建一个只包含单个消息的EventStream
pub fn once<Message>(message: Message) -> EventStream<Message>
where
    Message: 'static + Send,
{
    from_future(async { message })
}

/// 创建一个周期触发的EventStream
pub fn interval<Message, F>(duration: std::time::Duration, f: F) -> EventStream<Message>
where
    Message: 'static + Send,
    F: Fn() -> Message + Send + Sync + 'static,
{
    let stream = futures::stream::unfold((), move |_| async move {
        tokio::time::sleep(duration).await;
        Some((f(), ()))
    });

    EventStream::from(Box::pin(stream))
}

/// 将Iterator转换为EventStream
pub fn from_iter<Message, I>(iter: I) -> EventStream<Message>
where
    Message: 'static + Send,
    I: IntoIterator<Item = Message> + Send + 'static,
    I::IntoIter: Send,
{
    let stream = futures::stream::iter(iter);
    EventStream::from(Box::pin(stream))
}

/// 创建一个可以动态发送消息的EventStream
pub fn channel<Message>(buffer: usize) -> (mpsc::Sender<Message>, EventStream<Message>)
where
    Message: 'static + Send,
{
    let (sender, receiver) = mpsc::channel(buffer);
    (sender, EventStream::from(Box::pin(receiver)))
}

#[cfg(test)]
mod tests {
    use super::*;
    use futures::StreamExt;

    #[tokio::test]
    async fn test_from_stream() {
        let stream = futures::stream::iter(vec![1, 2, 3]);
        let mut event_stream = from_stream(stream);
        
        assert_eq!(event_stream.next().await, Some(1));
        assert_eq!(event_stream.next().await, Some(2));
        assert_eq!(event_stream.next().await, Some(3));
        assert_eq!(event_stream.next().await, None);
    }

    #[tokio::test]
    async fn test_from_future() {
        let future = async { 42 };
        let mut event_stream = from_future(future);
        
        assert_eq!(event_stream.next().await, Some(42));
        assert_eq!(event_stream.next().await, None);
    }

    #[tokio::test]
    async fn test_merge() {
        let stream1 = from_iter(vec![1, 2, 3]);
        let stream2 = from_iter(vec![4, 5, 6]);
        let stream3 = from_iter(vec![7, 8, 9]);
        
        let merged = merge(vec![stream1, stream2, stream3]);
        let results: Vec<i32> = merged.collect().await;
        
        // select_all会随机选择,所以只验证长度和包含的元素
        assert_eq!(results.len(), 9);
        for i in 1..=9 {
            assert!(results.contains(&i));
        }
    }

    #[tokio::test]
    async fn test_empty() {
        let mut empty_stream: EventStream<i32> = empty();
        assert_eq!(empty_stream.next().await, None);
    }

    #[tokio::test]
    async fn test_once() {
        let mut once_stream = once(42);
        assert_eq!(once_stream.next().await, Some(42));
        assert_eq!(once_stream.next().await, None);
    }

    #[tokio::test]
    async fn test_interval() {
        use std::sync::atomic::{AtomicUsize, Ordering};
        use std::sync::Arc;
        use tokio::time::timeout;

        let counter = Arc::new(AtomicUsize::new(0));
        let counter_clone = counter.clone();
        
        let interval_stream = interval(
            std::time::Duration::from_millis(10),
            move || {
                counter_clone.fetch_add(1, Ordering::SeqCst);
                42
            }
        );

        // 只取前3个值,避免无限等待
        let mut limited_stream = interval_stream.take(3);
        
        let results: Vec<i32> = limited_stream.collect().await;
        assert_eq!(results, vec![42, 42, 42]);
        assert_eq!(counter.load(Ordering::SeqCst), 3);
    }

    #[tokio::test]
    async fn test_from_iter() {
        let vec = vec![1, 2, 3, 4, 5];
        let mut iter_stream = from_iter(vec);
        
        for i in 1..=5 {
            assert_eq!(iter_stream.next().await, Some(i));
        }
        assert_eq!(iter_stream.next().await, None);
    }

    #[tokio::test]
    async fn test_channel() {
        let (sender, mut event_stream) = channel(10);
        
        // 发送消息
        sender.send(1).await.unwrap();
        sender.send(2).await.unwrap();
        sender.send(3).await.unwrap();
        
        // 由于channel是异步的,需要稍微等待一下
        tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
        
        // 丢弃sender,关闭通道
        drop(sender);
        
        assert_eq!(event_stream.next().await, Some(1));
        assert_eq!(event_stream.next().await, Some(2));
        assert_eq!(event_stream.next().await, Some(3));
        assert_eq!(event_stream.next().await, None);
    }
}

文件说明

这是一个用于创建和管理 EventStream 的工具函数集合。EventStream 似乎是某个框架(可能是 Iced GUI 框架)中用于处理异步事件流的核心类型。

主要函数

函数 描述 使用场景
from_stream 将普通Stream转换为EventStream 适配外部Stream到框架
from_future 将Future转换为单元素EventStream 处理一次性异步操作
merge 合并多个EventStream 组合多个事件源
empty 创建空EventStream 默认值或条件分支
once 创建包含单个消息的Stream 立即触发的事件
interval 创建周期性触发的Stream 定时器、心跳、轮询
from_iter 将Iterator转换为EventStream 处理静态数据集合
channel 创建可动态发送消息的Stream 复杂事件生产场景

核心模式

所有函数都遵循一个统一模式:接收各种数据源(Stream、Future、Iterator、定时器等),统一包装为 EventStream 类型。这提供了:

  1. 统一接口:所有事件源都表现为同一种类型
  2. 组合能力:可以轻松合并、转换事件流
  3. 灵活性:支持多种事件生产方式

应用场景

这个模块通常用于:

  • GUI应用:处理用户输入、系统事件
  • 实时系统:处理数据流、定时任务
  • 异步编程:统一处理各种异步数据源
  • 事件驱动架构:作为事件总线的基础

通过提供这些工具函数,开发者可以专注于业务逻辑,而不必关心不同类型事件流的底层实现细节。

相关推荐
楚国的小隐士14 小时前
为什么说Rust是对自闭症谱系人士友好的编程语言?
java·rust·编程·对比·自闭症·自闭症谱系障碍·神经多样性
Tomhex1 天前
Rust智能指针使用指南
rust
AI自动化工坊1 天前
Claw Code技术深度解析:Python+Rust混合架构的设计与实现
开发语言·人工智能·python·ai·架构·rust·开源
web前端进阶者2 天前
Rust初学知识点快速记忆
开发语言·后端·rust
一只幸运猫.2 天前
Rust实用工具特型-Clone
开发语言·后端·rust
咚为2 天前
深入浅出 Rust 内存顺序:从 CPU 重排到 Atomic Ordering
开发语言·后端·rust
咚为2 天前
深入浅出 Rust RefCell:打破静态检查的“紧箍咒”
开发语言·后端·rust
lUie INGA3 天前
rust web框架actix和axum比较
前端·人工智能·rust
沛沛rh453 天前
深入并发编程:从 C++ 到 Rust 的学习笔记
c++·笔记·学习·算法·rust
沛沛rh453 天前
力扣 42. 接雨水 - 高效双指针解法(Rust实现)详细题解
算法·leetcode·rust