1
- use hyper:: StatusCode ;
1
+ use std:: collections:: HashMap ;
2
+
3
+ use hyper:: { body:: Buf , Body , Response } ;
4
+
5
+ pub struct ResponseWrapper {
6
+ response : Response < Body > ,
7
+ }
8
+
9
+ impl ResponseWrapper {
10
+ pub fn new ( response : Response < Body > ) -> Self {
11
+ Self { response }
12
+ }
13
+ pub fn status ( & self ) -> u16 {
14
+ self . response . status ( ) . as_u16 ( )
15
+ }
16
+ pub fn headers ( & self ) -> std:: result:: Result < HashMap < & str , & str > , HeaderError > {
17
+ let headers = self . response . headers ( ) ;
18
+ let mut map = HashMap :: new ( ) ;
19
+ for ( key, value) in headers. iter ( ) {
20
+ let key = key. as_str ( ) ;
21
+ let value = match value. to_str ( ) {
22
+ Ok ( value) => value,
23
+ Err ( err) => return Err ( HeaderError :: new ( Box :: new ( err) ) ) ,
24
+ } ;
25
+ map. insert ( key, value) ;
26
+ }
27
+ Ok ( map)
28
+ }
29
+
30
+ pub async fn body_bytes ( self ) -> Result < Vec < u8 > > {
31
+ let body = self . response . into_body ( ) ;
32
+
33
+ let buf = match hyper:: body:: aggregate ( body) . await {
34
+ Ok ( buf) => buf,
35
+ Err ( err) => return Err ( Error :: HttpStream ( Box :: new ( err) ) ) ,
36
+ } ;
37
+
38
+ Ok ( buf. chunk ( ) . to_vec ( ) )
39
+ }
40
+ }
41
+
42
+ impl std:: fmt:: Debug for ResponseWrapper {
43
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
44
+ f. debug_struct ( "ResponseWrapper" )
45
+ . field ( "status" , & self . status ( ) )
46
+ . finish ( )
47
+ }
48
+ }
49
+
50
+ /// Error type for invalid response headers encountered in ResponseWrapper.
51
+ #[ derive( Debug ) ]
52
+ pub struct HeaderError {
53
+ /// Wrapped inner error providing details about the header issue.
54
+ inner_error : Box < dyn std:: error:: Error + Send + Sync + ' static > ,
55
+ }
56
+
57
+ impl HeaderError {
58
+ /// Constructs a new `HeaderError` wrapping an existing error.
59
+ pub fn new ( err : Box < dyn std:: error:: Error + Send + Sync + ' static > ) -> Self {
60
+ HeaderError { inner_error : err }
61
+ }
62
+ }
63
+
64
+ impl std:: fmt:: Display for HeaderError {
65
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
66
+ write ! ( f, "Invalid response header: {}" , self . inner_error)
67
+ }
68
+ }
69
+
70
+ impl std:: error:: Error for HeaderError {
71
+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
72
+ Some ( self . inner_error . as_ref ( ) )
73
+ }
74
+ }
2
75
3
76
/// Error type returned from this library's functions.
4
77
#[ derive( Debug ) ]
@@ -8,7 +81,7 @@ pub enum Error {
8
81
/// An invalid request parameter
9
82
InvalidParameter ( Box < dyn std:: error:: Error + Send + Sync + ' static > ) ,
10
83
/// The HTTP response could not be handled.
11
- UnexpectedResponse ( StatusCode ) ,
84
+ UnexpectedResponse ( ResponseWrapper ) ,
12
85
/// An error reading from the HTTP response body.
13
86
HttpStream ( Box < dyn std:: error:: Error + Send + Sync + ' static > ) ,
14
87
/// The HTTP response stream ended
@@ -32,7 +105,10 @@ impl std::fmt::Display for Error {
32
105
TimedOut => write ! ( f, "timed out" ) ,
33
106
StreamClosed => write ! ( f, "stream closed" ) ,
34
107
InvalidParameter ( err) => write ! ( f, "invalid parameter: {err}" ) ,
35
- UnexpectedResponse ( status_code) => write ! ( f, "unexpected response: {status_code}" ) ,
108
+ UnexpectedResponse ( r) => {
109
+ let status = r. status ( ) ;
110
+ write ! ( f, "unexpected response: {status}" )
111
+ }
36
112
HttpStream ( err) => write ! ( f, "http error: {err}" ) ,
37
113
Eof => write ! ( f, "eof" ) ,
38
114
UnexpectedEof => write ! ( f, "unexpected eof" ) ,
0 commit comments