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 get<U: DeserializeOwned>(
52 &self,
53 endpoint: &str,
54 ) -> Result<UmbralResponse<U>, Box<dyn Error>> {
55 let uri = hyperlocal::Uri::new(&self.socket, endpoint).into();
56 let response = self.client.get(uri).await?;
57 let status = response.status().as_u16();
58 let body_bytes = response.into_body().collect().await?.to_bytes();
59 let data: U = serde_json::from_reader(body_bytes.reader())?;
60 return Ok(UmbralResponse::new(status, Some(data)));
61 }
62
63 pub async fn post<T: Serialize, U: DeserializeOwned>(
64 &self,
65 endpoint: &str,
66 request: &T,
67 ) -> Result<UmbralResponse<U>, Box<dyn Error>> {
68 let body_bytes = serde_json::to_vec(&*request).unwrap();
69 let request_body = Full::new(Bytes::from(body_bytes))
70 .map_err(|e| match e {})
71 .boxed();
72
73 let request = Request::builder()
74 .method(Method::POST)
75 .uri(Uri::new(&self.socket, endpoint))
76 .header(header::CONTENT_TYPE, "application/json")
77 .body(request_body)?;
78
79 let response = self.client.request(request).await?;
80 let status = response.status().as_u16();
81 let body_bytes = response.into_body().collect().await?.to_bytes();
82 let data: U = serde_json::from_reader(body_bytes.reader())?;
83 return Ok(UmbralResponse::new(status, Some(data)));
84 }
85
86 pub async fn post_raw<T: Serialize>(
87 &self,
88 endpoint: &str,
89 request: &T,
90 ) -> Result<UmbralResponse<()>, Box<dyn Error>> {
91 let body_bytes = serde_json::to_vec(&*request)?;
92 let request_body = Full::new(Bytes::from(body_bytes))
93 .map_err(|e| match e {})
94 .boxed();
95
96 let request = Request::builder()
97 .method(Method::POST)
98 .uri(Uri::new(&self.socket, endpoint))
99 .header(header::CONTENT_TYPE, "application/json")
100 .body(request_body)?;
101
102 let response = self.client.request(request).await?;
103 let status = response.status().as_u16();
104 return Ok(UmbralResponse::new(status, None));
105 }
106
107 pub async fn post_trigger(&self, endpoint: &str) -> Result<UmbralResponse<()>, Box<dyn Error>> {
108 let request_body = Empty::new().map_err(|e| match e {}).boxed();
109 let request = Request::builder()
110 .method(Method::POST)
111 .uri(Uri::new(&self.socket, endpoint))
112 .header(header::CONTENT_TYPE, "application/json")
113 .body(request_body)?;
114
115 let response = self.client.request(request).await?;
116 let status = response.status().as_u16();
117 return Ok(UmbralResponse::new(status, None));
118 }
119}