• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tu6ge / oss-rs / 5874371460

pending completion
5874371460

Pull #24

github

tu6ge
chore: add clippy deprecated_semver rule
Pull Request #24: Branch0.12

39 of 39 new or added lines in 4 files covered. (100.0%)

6180 of 6422 relevant lines covered (96.23%)

9.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.68
/src/builder.rs
1
//! 封装了 reqwest::RequestBuilder 模块
2✔
2

3
use async_trait::async_trait;
4
use http::Method;
5
use reqwest::{
6
    header::{HeaderMap, HeaderName, HeaderValue},
7
    Body, IntoUrl,
8
};
9
use std::error::Error;
10
#[cfg(feature = "blocking")]
11
use std::rc::Rc;
12
use std::{fmt::Display, sync::Arc, time::Duration};
13

14
use crate::auth::AuthError;
15
#[cfg(feature = "blocking")]
16
use crate::blocking::builder::ClientWithMiddleware as BlockingClientWithMiddleware;
17
use crate::{
18
    client::Client as AliClient,
19
    config::{BucketBase, InvalidConfig},
20
    errors::OssService,
21
};
22
use reqwest::{Client, Request, Response};
23

24
#[cfg(test)]
25
pub(crate) mod test;
26

27
pub trait PointerFamily
28
where
29
    Self::Bucket: std::fmt::Debug + Clone + Default,
30
{
31
    type PointerType;
32
    type Bucket;
33
}
34

35
#[derive(Default, Debug)]
1✔
36
pub struct ArcPointer;
37

38
impl PointerFamily for ArcPointer {
39
    type PointerType = Arc<AliClient<ClientWithMiddleware>>;
40
    type Bucket = Arc<BucketBase>;
41
}
42

43
#[cfg(feature = "blocking")]
44
#[derive(Default, Debug)]
1✔
45
pub struct RcPointer;
46

47
#[cfg(feature = "blocking")]
48
impl PointerFamily for RcPointer {
49
    type PointerType = Rc<AliClient<BlockingClientWithMiddleware>>;
50
    type Bucket = Rc<BucketBase>;
51
}
52

53
#[derive(Default, Clone)]
134✔
54
pub struct ClientWithMiddleware {
55
    inner: Client,
67✔
56
    middleware: Option<Arc<dyn Middleware>>,
67✔
57
}
58

59
#[async_trait]
60
pub trait Middleware: 'static + Send + Sync {
61
    async fn handle(&self, request: Request) -> Result<Response, BuilderError>;
62
}
63

64
impl ClientWithMiddleware {
65
    pub fn new(inner: Client) -> Self {
×
66
        Self {
×
67
            inner,
68
            middleware: None,
×
69
        }
70
    }
×
71

72
    pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
29✔
73
        RequestBuilder {
29✔
74
            inner: self.inner.request(method, url),
29✔
75
            middleware: self.middleware.clone(),
29✔
76
        }
77
    }
29✔
78

79
    pub fn middleware(&mut self, middleware: Arc<dyn Middleware>) {
13✔
80
        self.middleware = Some(middleware);
13✔
81
    }
13✔
82
}
83

84
pub struct RequestBuilder {
85
    inner: reqwest::RequestBuilder,
86
    middleware: Option<Arc<dyn Middleware>>,
87
}
88

89
impl RequestBuilder {
90
    #[allow(dead_code)]
91
    pub(crate) fn header<K, V>(self, key: K, value: V) -> Self
92
    where
93
        HeaderName: TryFrom<K>,
94
        <HeaderName as TryFrom<K>>::Error: Into<http::Error>,
95
        HeaderValue: TryFrom<V>,
96
        <HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
97
    {
98
        RequestBuilder {
99
            inner: self.inner.header(key, value),
100
            ..self
101
        }
102
    }
103

104
    pub(crate) fn headers(self, headers: HeaderMap) -> Self {
29✔
105
        RequestBuilder {
29✔
106
            inner: self.inner.headers(headers),
29✔
107
            ..self
108
        }
109
    }
29✔
110

111
    pub(crate) fn body<T: Into<Body>>(self, body: T) -> Self {
1✔
112
        RequestBuilder {
1✔
113
            inner: self.inner.body(body),
1✔
114
            ..self
115
        }
116
    }
1✔
117

118
    pub(crate) fn timeout(self, timeout: Duration) -> Self {
1✔
119
        RequestBuilder {
1✔
120
            inner: self.inner.timeout(timeout),
1✔
121
            ..self
122
        }
123
    }
1✔
124

125
    #[allow(dead_code)]
126
    pub(crate) fn build(self) -> reqwest::Result<Request> {
3✔
127
        self.inner.build()
3✔
128
    }
3✔
129

130
    /// 发送请求,获取响应后,直接返回 Response
131
    pub async fn send(self) -> Result<Response, BuilderError> {
×
132
        match self.middleware {
133
            Some(m) => {
134
                m.handle(self.inner.build().map_err(BuilderError::from)?)
135
                    .await
136
            }
137
            None => self.inner.send().await.map_err(BuilderError::from),
138
        }
139
    }
×
140

141
    /// 发送请求,获取响应后,解析 xml 文件,如果有错误,返回 Err 否则返回 Response
142
    pub async fn send_adjust_error(self) -> Result<Response, BuilderError> {
46✔
143
        match self.middleware {
14✔
144
            Some(m) => {
13✔
145
                m.handle(self.inner.build().map_err(BuilderError::from)?)
26✔
146
                    .await
13✔
147
            }
13✔
148
            None => check_http_status(self.inner.send().await.map_err(BuilderError::from)?)
9✔
149
                .await
1✔
150
                .map_err(BuilderError::from),
151
        }
152
    }
40✔
153
}
154

155
#[derive(Debug)]
24✔
156
#[non_exhaustive]
157
pub struct BuilderError {
158
    pub(crate) kind: BuilderErrorKind,
12✔
159
}
160

161
impl BuilderError {
162
    #[cfg(test)]
163
    pub(crate) fn bar() -> Self {
2✔
164
        Self {
2✔
165
            kind: BuilderErrorKind::Bar,
2✔
166
        }
167
    }
2✔
168
}
169

170
#[derive(Debug)]
12✔
171
#[non_exhaustive]
172
pub(crate) enum BuilderErrorKind {
173
    Reqwest(Box<reqwest::Error>),
1✔
174

175
    OssService(Box<OssService>),
6✔
176

177
    Auth(Box<AuthError>),
1✔
178

179
    Config(Box<InvalidConfig>),
1✔
180

181
    #[cfg(test)]
182
    Bar,
183
}
184

185
impl Display for BuilderError {
186
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8✔
187
        use BuilderErrorKind::*;
188
        match &self.kind {
8✔
189
            Reqwest(_) => "reqwest error".fmt(f),
1✔
190
            OssService(_) => "http status is not success".fmt(f),
1✔
191
            Auth(_) => "aliyun auth failed".fmt(f),
1✔
192
            Config(_) => "oss config error".fmt(f),
1✔
193
            #[cfg(test)]
194
            Bar => "bar".fmt(f),
4✔
195
        }
196
    }
8✔
197
}
198

199
impl Error for BuilderError {
200
    fn source(&self) -> Option<&(dyn Error + 'static)> {
5✔
201
        use BuilderErrorKind::*;
202
        match &self.kind {
5✔
203
            Reqwest(e) => Some(e),
1✔
204
            OssService(e) => Some(e),
1✔
205
            Auth(e) => Some(e),
1✔
206
            Config(e) => Some(e),
1✔
207
            #[cfg(test)]
208
            Bar => None,
1✔
209
        }
210
    }
5✔
211
}
212

213
impl From<reqwest::Error> for BuilderError {
214
    fn from(value: reqwest::Error) -> Self {
1✔
215
        Self {
1✔
216
            kind: BuilderErrorKind::Reqwest(Box::new(value)),
1✔
217
        }
218
    }
1✔
219
}
220
impl From<OssService> for BuilderError {
221
    fn from(value: OssService) -> Self {
23✔
222
        Self {
23✔
223
            kind: BuilderErrorKind::OssService(Box::new(value)),
23✔
224
        }
225
    }
23✔
226
}
227

228
impl From<AuthError> for BuilderError {
229
    fn from(value: AuthError) -> Self {
1✔
230
        Self {
1✔
231
            kind: BuilderErrorKind::Auth(Box::new(value)),
1✔
232
        }
233
    }
1✔
234
}
235
impl From<InvalidConfig> for BuilderError {
236
    fn from(value: InvalidConfig) -> Self {
1✔
237
        Self {
1✔
238
            kind: BuilderErrorKind::Config(Box::new(value)),
1✔
239
        }
240
    }
1✔
241
}
242

243
pub(crate) async fn check_http_status(response: Response) -> Result<Response, BuilderError> {
22✔
244
    if response.status().is_success() {
4✔
245
        return Ok(response);
2✔
246
    }
247
    let url = response.url().clone();
2✔
248
    let status = response.status();
2✔
249
    let text = response.text().await?;
2✔
250
    Err(OssService::new2(text, &status, url).into())
2✔
251
}
20✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc