awpak_web_client/
lib.rs

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}