1use http_body_util::BodyExt;
2use http_body_util::Empty;
3use http_body_util::Full;
4use http_body_util::combinators::BoxBody;
5use hyper::Method;
6use hyper::Request;
7use hyper::body::{Buf, Bytes};
8use hyper::header;
9use hyper_util::client::legacy::Client;
10use hyper_util::rt::tokio::TokioExecutor;
11use hyperlocal::UnixConnector;
12use hyperlocal::Uri;
13use serde::Serialize;
14use serde::de::DeserializeOwned;
15use std::convert::Infallible;
16
17use std::error::Error;
18
19pub struct UmbralResponse<T: DeserializeOwned> {
20 pub status: u16,
21 pub response: Option<T>,
22}
23
24impl<T: DeserializeOwned> UmbralResponse<T> {
25 fn new(status: u16, response: Option<T>) -> Self {
26 return UmbralResponse {
27 status: status,
28 response: response,
29 };
30 }
31}
32
33type BoxedBody = BoxBody<Bytes, Infallible>;
34type HyperClient = Client<UnixConnector, BoxedBody>;
35#[derive(Clone)]
36pub struct UmbralSocket {
37 socket: String,
38 client: HyperClient,
39}
40
41impl UmbralSocket {
42 pub fn new(socket: &str) -> UmbralSocket {
43 let connector = UnixConnector;
44 let client: HyperClient = Client::builder(TokioExecutor::new()).build(connector);
45 return UmbralSocket {
46 socket: String::from(socket),
47 client: client,
48 };
49 }
50
51 pub async fn post<T: Serialize, U: DeserializeOwned>(
52 &self,
53 endpoint: &str,
54 request: &T,
55 ) -> Result<UmbralResponse<U>, Box<dyn Error>> {
56 let body_bytes = serde_json::to_vec(&*request).unwrap();
57 let request_body = Full::new(Bytes::from(body_bytes))
58 .map_err(|e| match e {})
59 .boxed();
60
61 let request = Request::builder()
62 .method(Method::POST)
63 .uri(Uri::new(&self.socket, endpoint))
64 .header(header::CONTENT_TYPE, "application/json")
65 .body(request_body)?;
66
67 let response = self.client.request(request).await?;
68 let status = response.status().as_u16();
69 let body_bytes = response.into_body().collect().await?.to_bytes();
70 let data: U = serde_json::from_reader(body_bytes.reader())?;
71 return Ok(UmbralResponse::new(status, Some(data)));
72 }
73
74 pub async fn post_raw<T: Serialize>(
75 &self,
76 endpoint: &str,
77 request: &T,
78 ) -> Result<UmbralResponse<()>, Box<dyn Error>> {
79 let body_bytes = serde_json::to_vec(&*request)?;
80 let request_body = Full::new(Bytes::from(body_bytes))
81 .map_err(|e| match e {})
82 .boxed();
83
84 let request = Request::builder()
85 .method(Method::POST)
86 .uri(Uri::new(&self.socket, endpoint))
87 .header(header::CONTENT_TYPE, "application/json")
88 .body(request_body)?;
89
90 let response = self.client.request(request).await?;
91 let status = response.status().as_u16();
92 return Ok(UmbralResponse::new(status, None));
93 }
94
95 pub async fn post_trigger(&self, endpoint: &str) -> Result<UmbralResponse<()>, Box<dyn Error>> {
96 let request_body = Empty::new().map_err(|e| match e {}).boxed();
97 let request = Request::builder()
98 .method(Method::POST)
99 .uri(Uri::new(&self.socket, endpoint))
100 .header(header::CONTENT_TYPE, "application/json")
101 .body(request_body)?;
102
103 let response = self.client.request(request).await?;
104 let status = response.status().as_u16();
105 return Ok(UmbralResponse::new(status, None));
106 }
107
108 pub async fn get<T: Serialize>(
109 &self,
110 endpoint: &str,
111 ) -> Result<UmbralResponse<()>, Box<dyn Error>> {
112 let uri = hyperlocal::Uri::new(&self.socket, endpoint).into();
113 let response = self.client.get(uri).await?;
114 let status = response.status().as_u16();
115 return Ok(UmbralResponse::new(status, None));
116 }
117}