fast_pull/core/
mod.rs

1extern crate alloc;
2use crate::Event;
3use alloc::sync::Arc;
4use core::{
5    fmt::Debug,
6    sync::atomic::{AtomicBool, Ordering},
7};
8use kanal::AsyncReceiver;
9use tokio::{
10    sync::Mutex,
11    task::{JoinError, JoinHandle},
12};
13
14mod macros;
15#[cfg(test)]
16pub mod mock;
17pub mod multi;
18pub mod single;
19
20#[derive(Debug)]
21pub struct DownloadResult<ReadError, WriteError> {
22    pub event_chain: AsyncReceiver<Event<ReadError, WriteError>>,
23    handle: Arc<Mutex<Option<JoinHandle<()>>>>,
24    is_running: Arc<AtomicBool>,
25}
26
27impl<RE, WE> Clone for DownloadResult<RE, WE> {
28    fn clone(&self) -> Self {
29        Self {
30            event_chain: self.event_chain.clone(),
31            handle: self.handle.clone(),
32            is_running: self.is_running.clone(),
33        }
34    }
35}
36
37impl<ReadError, WriteError> DownloadResult<ReadError, WriteError> {
38    pub fn new(
39        event_chain: AsyncReceiver<Event<ReadError, WriteError>>,
40        handle: JoinHandle<()>,
41        is_running: Arc<AtomicBool>,
42    ) -> Self {
43        Self {
44            event_chain,
45            handle: Arc::new(Mutex::new(Some(handle))),
46            is_running,
47        }
48    }
49
50    pub async fn join(&self) -> Result<(), JoinError> {
51        if let Some(handle) = self.handle.lock().await.take() {
52            handle.await?
53        }
54        Ok(())
55    }
56
57    /// 取消后记得调用 `self.join().await` 等待真正的退出
58    pub fn cancel(&self) {
59        self.is_running.store(false, Ordering::Relaxed);
60    }
61}