use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use tokio::sync::broadcast;
use crate::error::TusError;
use crate::info::{UploadId, UploadInfo, UploadInfoChanges};
#[derive(Debug, Clone)]
pub enum HookEvent {
UploadCreated { info: UploadInfo },
UploadFinished { info: UploadInfo },
UploadTerminated { id: UploadId },
UploadProgress { info: UploadInfo },
}
pub type HookFuture<T> = Pin<Box<dyn Future<Output = T> + Send + 'static>>;
pub type PreCreateCallback =
Arc<dyn Fn(UploadInfo) -> HookFuture<Result<UploadInfoChanges, TusError>> + Send + Sync>;
pub type PreFinishCallback =
Arc<dyn Fn(UploadInfo) -> HookFuture<Result<(), TusError>> + Send + Sync>;
pub type PreTerminateCallback =
Arc<dyn Fn(UploadInfo) -> HookFuture<Result<(), TusError>> + Send + Sync>;
pub type HookSender = broadcast::Sender<HookEvent>;
#[derive(Clone, Default)]
pub struct HookConfig {
pub channel_capacity: usize,
pub pre_create: Option<PreCreateCallback>,
pub pre_finish: Option<PreFinishCallback>,
pub pre_terminate: Option<PreTerminateCallback>,
}
impl std::fmt::Debug for HookConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("HookConfig")
.field("channel_capacity", &self.channel_capacity)
.field("pre_create", &self.pre_create.is_some())
.field("pre_finish", &self.pre_finish.is_some())
.field("pre_terminate", &self.pre_terminate.is_some())
.finish()
}
}
impl HookConfig {
pub fn has_hooks(&self) -> bool {
self.channel_capacity > 0
|| self.pre_create.is_some()
|| self.pre_finish.is_some()
|| self.pre_terminate.is_some()
}
}