1
2pub mod request;
3pub mod response;
4use std::{collections::HashMap, time::{Duration, Instant}};
5
6use reqwest::RequestBuilder;
7
8use crate::{request::{AwpakBody, AwpakHeader, AwpakMethod, AwpakQueryParam, AwpakRequest}, response::AwpakResponse};
9
10pub async fn send_request( request : AwpakRequest ) -> Result<AwpakResponse, reqwest::Error>
11{
12 let builder = request_builder( &request.url, request.method );
13
14 let builder = append_headers(builder, request.headers );
15
16 let mut builder = append_query_params( builder, request.query_params );
17
18 if let Some( t ) = request.timeout
19 {
20 if t > 0 { builder = builder.timeout( Duration::from_secs( t ) ) }
21 }
22
23 let builder = match request.body
24 {
25 Some( b ) => append_body( builder, b ),
26 _ => builder
27 };
28
29 send( builder ).await
30}
31
32async fn send( builder : RequestBuilder ) -> Result<AwpakResponse, reqwest::Error>
33{
34 let start = Instant::now();
35
36 let response = builder.send().await?;
37
38 let duration = start.elapsed();
39
40 let version = format!( "{:?}", response.version() );
41
42 let status = usize::from( response.status().as_u16() );
43
44 let headers = response.headers().into_iter()
45 .fold(
46 HashMap::new(),
47 | mut a, ( n, v ) |
48 {
49 a.insert( n.to_string(), v.to_str().unwrap_or( "" ).to_string() );
50
51 a
52 }
53 );
54
55 let text = response.text().await?;
56
57 Ok(
58 AwpakResponse
59 {
60 version,
61 status,
62 headers,
63 text,
64 time_millis : duration.as_millis(),
65 time_str : format!( "{:?}", duration )
66 }
67 )
68}
69
70fn append_query_params( builder : RequestBuilder, query_params : Vec<AwpakQueryParam> ) -> RequestBuilder
71{
72 if query_params.len() == 0 { return builder }
73
74 builder.query(
75 query_params.into_iter()
76 .map( | q | ( q.name, q.value ) )
77 .collect::<Vec<_>>()
78 .as_slice()
79 )
80}
81
82fn append_headers( mut builder : RequestBuilder, headers : Vec<AwpakHeader> ) -> RequestBuilder
83{
84 if headers.len() == 0 { return builder; }
85
86 for h in headers
87 {
88 builder = builder.header( h.name, h.value )
89 }
90
91 builder
92}
93
94fn append_body( builder : RequestBuilder, body : AwpakBody ) -> RequestBuilder
95{
96 match body
97 {
98 AwpakBody::Json( j ) => builder.json( &j ),
99 AwpakBody::Form( f ) =>
100 {
101 if f.len() == 0
102 {
103 builder
104 }
105 else
106 {
107 builder.form(
108 f.into_iter()
109 .map( | q | ( q.name, q.value ) )
110 .collect::<Vec<_>>()
111 .as_slice()
112 )
113 }
114 }
115 }
116}
117
118fn request_builder( url : &str, method : AwpakMethod ) -> RequestBuilder
119{
120 let client = reqwest::Client::new();
121
122 client.request( method.into(), url )
123}