qiniu_http/
callback.rs

1use anyhow::Result as AnyResult;
2use http::{header::HeaderName, HeaderValue, StatusCode};
3use std::{
4    fmt::{self, Debug},
5    ops::Deref,
6};
7
8macro_rules! impl_callback {
9    ($name:ident, $name_str:literal, $callback:path) => {
10        impl<'r> $name<'r> {
11            /// 创建回调函数
12            #[inline]
13            pub fn new(callback: impl $callback + Send + Sync + 'r) -> Self {
14                Self::Boxed(Box::new(callback))
15            }
16
17            /// 创建回调函数的引用
18            #[inline]
19            pub fn reference(callback: &'r (dyn $callback + Send + Sync + 'r)) -> Self {
20                Self::Referenced(callback)
21            }
22        }
23
24        impl<'r, T: $callback + Send + Sync + 'r> From<T> for $name<'r> {
25            #[inline]
26            fn from(callback: T) -> Self {
27                Self::new(callback)
28            }
29        }
30
31        impl<'r> Deref for $name<'r> {
32            type Target = (dyn $callback + Send + Sync + 'r);
33
34            #[inline]
35            fn deref(&self) -> &Self::Target {
36                match self {
37                    Self::Boxed(callback) => callback.deref(),
38                    Self::Referenced(callback) => callback,
39                }
40            }
41        }
42
43        impl Debug for $name<'_> {
44            #[inline]
45            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46                f.debug_struct($name_str).finish()
47            }
48        }
49    };
50}
51
52/// 上传进度回调
53pub enum OnProgressCallback<'r> {
54    /// 用 Box 包装的上传进度回调
55    Boxed(Box<dyn Fn(TransferProgressInfo) -> AnyResult<()> + Send + Sync + 'r>),
56    /// 上传进度回调的引用
57    Referenced(&'r (dyn Fn(TransferProgressInfo) -> AnyResult<()> + Send + Sync + 'r)),
58}
59impl_callback!(OnProgressCallback, "OnProgressCallback", Fn(TransferProgressInfo) -> AnyResult<()>);
60
61pub(super) type OnProgress<'r> = &'r (dyn Fn(TransferProgressInfo<'_>) -> AnyResult<()> + Send + Sync + 'r);
62
63/// 响应状态回调
64pub enum OnStatusCodeCallback<'r> {
65    /// 用 Box 包装的响应状态回调
66    Boxed(Box<dyn Fn(StatusCode) -> AnyResult<()> + Send + Sync + 'r>),
67    /// 响应状态回调的引用
68    Referenced(&'r (dyn Fn(StatusCode) -> AnyResult<()> + Send + Sync + 'r)),
69}
70impl_callback!(OnStatusCodeCallback, "OnStatusCodeCallback", Fn(StatusCode) -> AnyResult<()>);
71
72pub(super) type OnStatusCode<'r> = &'r (dyn Fn(StatusCode) -> AnyResult<()> + Send + Sync + 'r);
73
74type OnHeaderCallbackFn<'r> = Box<dyn Fn(&HeaderName, &HeaderValue) -> AnyResult<()> + Send + Sync + 'r>;
75type OnHeaderCallbackFnRef<'r> = &'r (dyn Fn(&HeaderName, &HeaderValue) -> AnyResult<()> + Send + Sync + 'r);
76
77/// 接受到响应 Header 回调
78pub enum OnHeaderCallback<'r> {
79    /// 用 Box 包装的接受到响应 Header 回调
80    Boxed(OnHeaderCallbackFn<'r>),
81    /// 接受到响应 Header 回调的引用
82    Referenced(OnHeaderCallbackFnRef<'r>),
83}
84impl_callback!(OnHeaderCallback, "OnHeaderCallback", Fn(&HeaderName, &HeaderValue) -> AnyResult<()>);
85
86pub(super) type OnHeader<'r> = &'r (dyn Fn(&HeaderName, &HeaderValue) -> AnyResult<()> + Send + Sync + 'r);
87
88/// 数据传输进度信息
89#[derive(Debug, Clone, Copy)]
90pub struct TransferProgressInfo<'b> {
91    transferred_bytes: u64,
92    total_bytes: u64,
93    body: &'b [u8],
94}
95
96impl<'b> TransferProgressInfo<'b> {
97    /// 创建数据传输进度信息
98    #[inline]
99    pub fn new(transferred_bytes: u64, total_bytes: u64, body: &'b [u8]) -> Self {
100        Self {
101            transferred_bytes,
102            total_bytes,
103            body,
104        }
105    }
106
107    /// 获取已经传输的数据量
108    ///
109    /// 单位为字节
110    #[inline]
111    pub fn transferred_bytes(&self) -> u64 {
112        self.transferred_bytes
113    }
114
115    /// 获取总共需要传输的数据量
116    ///
117    /// 单位为字节
118    #[inline]
119    pub fn total_bytes(&self) -> u64 {
120        self.total_bytes
121    }
122
123    /// 获取当前传输的数据
124    #[inline]
125    pub fn body(&self) -> &[u8] {
126        self.body
127    }
128}