1use std::future::Future;
2use std::pin::Pin;
3use std::sync::Arc;
4
5use tokio::sync::broadcast;
6
7use crate::error::TusError;
8use crate::info::{UploadId, UploadInfo, UploadInfoChanges};
9
10#[derive(Debug, Clone)]
12pub enum HookEvent {
13 UploadCreated { info: UploadInfo },
15 UploadFinished { info: UploadInfo },
17 UploadTerminated { id: UploadId },
19 UploadProgress { info: UploadInfo },
21}
22
23pub type HookFuture<T> = Pin<Box<dyn Future<Output = T> + Send + 'static>>;
25
26pub type PreCreateCallback =
29 Arc<dyn Fn(UploadInfo) -> HookFuture<Result<UploadInfoChanges, TusError>> + Send + Sync>;
30
31pub type PreFinishCallback =
34 Arc<dyn Fn(UploadInfo) -> HookFuture<Result<(), TusError>> + Send + Sync>;
35
36pub type PreTerminateCallback =
39 Arc<dyn Fn(UploadInfo) -> HookFuture<Result<(), TusError>> + Send + Sync>;
40
41pub type HookSender = broadcast::Sender<HookEvent>;
44
45#[derive(Clone, Default)]
47pub struct HookConfig {
48 pub channel_capacity: usize,
50 pub pre_create: Option<PreCreateCallback>,
51 pub pre_finish: Option<PreFinishCallback>,
52 pub pre_terminate: Option<PreTerminateCallback>,
53}
54
55impl std::fmt::Debug for HookConfig {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 f.debug_struct("HookConfig")
58 .field("channel_capacity", &self.channel_capacity)
59 .field("pre_create", &self.pre_create.is_some())
60 .field("pre_finish", &self.pre_finish.is_some())
61 .field("pre_terminate", &self.pre_terminate.is_some())
62 .finish()
63 }
64}
65
66impl HookConfig {
67 pub fn has_hooks(&self) -> bool {
69 self.channel_capacity > 0
70 || self.pre_create.is_some()
71 || self.pre_finish.is_some()
72 || self.pre_terminate.is_some()
73 }
74}