qiniu-download-manager 0.2.2

Qiniu Download Manager for Rust
Documentation
use super::DownloadingProgressInfo;
use anyhow::Result as AnyResult;
use qiniu_apis::{
    http::ResponseParts as HttpResponseParts,
    http_client::{RequestBuilderParts, Response, ResponseError},
};
use std::fmt::{self, Debug};

type BeforeRequestCallback<'c> = Box<dyn Fn(&mut RequestBuilderParts<'_>) -> AnyResult<()> + Send + Sync + 'c>;
type DownloadProgressCallback<'c> = Box<dyn Fn(DownloadingProgressInfo) -> AnyResult<()> + Send + Sync + 'c>;
type AfterResponseOkCallback<'c> = Box<dyn Fn(&mut HttpResponseParts) -> AnyResult<()> + Send + Sync + 'c>;
type AfterResponseErrorCallback<'c> = Box<dyn Fn(&mut ResponseError) -> AnyResult<()> + Send + Sync + 'c>;

#[derive(Default)]
pub(super) struct Callbacks<'a> {
    before_request_callbacks: Vec<BeforeRequestCallback<'a>>,
    download_progress_callbacks: Vec<DownloadProgressCallback<'a>>,
    after_response_ok_callbacks: Vec<AfterResponseOkCallback<'a>>,
    after_response_error_callbacks: Vec<AfterResponseErrorCallback<'a>>,
}

impl<'a> Callbacks<'a> {
    pub(super) fn insert_before_request_callback(
        &mut self,
        callback: impl Fn(&mut RequestBuilderParts<'_>) -> AnyResult<()> + Send + Sync + 'a,
    ) -> &mut Self {
        self.before_request_callbacks.push(Box::new(callback));
        self
    }

    pub(super) fn insert_download_progress_callback(
        &mut self,
        callback: impl Fn(DownloadingProgressInfo) -> AnyResult<()> + Send + Sync + 'a,
    ) -> &mut Self {
        self.download_progress_callbacks.push(Box::new(callback));
        self
    }

    pub(super) fn insert_after_response_ok_callback(
        &mut self,
        callback: impl Fn(&mut HttpResponseParts) -> AnyResult<()> + Send + Sync + 'a,
    ) -> &mut Self {
        self.after_response_ok_callbacks.push(Box::new(callback));
        self
    }

    pub(super) fn insert_after_response_error_callback(
        &mut self,
        callback: impl Fn(&mut ResponseError) -> AnyResult<()> + Send + Sync + 'a,
    ) -> &mut Self {
        self.after_response_error_callbacks.push(Box::new(callback));
        self
    }

    pub(super) fn before_request(&self, builder_parts: &mut RequestBuilderParts) -> AnyResult<()> {
        self.before_request_callbacks
            .iter()
            .try_for_each(|callback| callback(builder_parts))
    }

    pub(super) fn download_progress(&self, progress_info: DownloadingProgressInfo) -> AnyResult<()> {
        self.download_progress_callbacks
            .iter()
            .try_for_each(|callback| callback(progress_info))
    }

    pub(super) fn after_response<B>(&self, result: &mut Result<Response<B>, ResponseError>) -> AnyResult<()> {
        match result {
            Ok(response) => self.after_response_ok(response.parts_mut()),
            Err(err) => self.after_response_error(err),
        }
    }

    fn after_response_ok(&self, response_parts: &mut HttpResponseParts) -> AnyResult<()> {
        self.after_response_ok_callbacks
            .iter()
            .try_for_each(|callback| callback(response_parts))
    }

    fn after_response_error(&self, error: &mut ResponseError) -> AnyResult<()> {
        self.after_response_error_callbacks
            .iter()
            .try_for_each(|callback| callback(error))
    }
}

impl Debug for Callbacks<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Callbacks").finish()
    }
}