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 pub fn cancel(&self) {
59 self.is_running.store(false, Ordering::Relaxed);
60 }
61}