umbral_socket/
lib.rs

1use http_body_util::BodyExt;
2use http_body_util::Empty;
3use http_body_util::Full;
4use hyper::Method;
5use hyper::Request;
6use hyper::body::{Buf, Bytes};
7use hyper::header;
8use hyper_util::client::legacy::Client;
9use hyper_util::rt::tokio::TokioExecutor;
10use hyperlocal::UnixConnector;
11use hyperlocal::Uri;
12use serde::Serialize;
13use serde::de::DeserializeOwned;
14
15use std::error::Error;
16
17pub struct UmbralResponse<T: DeserializeOwned> {
18    pub status: u16,
19    pub response: Option<T>,
20}
21
22impl<T: DeserializeOwned> UmbralResponse<T> {
23    fn new(status: u16, response: Option<T>) -> Self {
24        return UmbralResponse {
25            status: status,
26            response: response,
27        };
28    }
29}
30
31type EmptyClient = Client<UnixConnector, Empty<Bytes>>;
32type FullClient = Client<UnixConnector, Full<Bytes>>;
33
34#[derive(Clone)]
35pub struct UmbralSocket {
36    socket: String,
37    empty: EmptyClient,
38    full: FullClient,
39}
40
41impl UmbralSocket {
42    pub fn new(socket: &str) -> UmbralSocket {
43        let connector = UnixConnector;
44        return UmbralSocket {
45            socket: String::from(socket),
46            empty: Client::builder(TokioExecutor::new()).build(connector),
47            full: Client::builder(TokioExecutor::new()).build(connector),
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.empty.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
71        let request = Request::builder()
72            .method(Method::POST)
73            .uri(Uri::new(&self.socket, endpoint))
74            .header(header::CONTENT_TYPE, "application/json")
75            .body(request_body)?;
76
77        let response = self.full.request(request).await?;
78        let status = response.status().as_u16();
79        let body_bytes = response.into_body().collect().await?.to_bytes();
80        let data: U = serde_json::from_reader(body_bytes.reader())?;
81        return Ok(UmbralResponse::new(status, Some(data)));
82    }
83
84    pub async fn post_raw<T: Serialize>(
85        &self,
86        endpoint: &str,
87        request: &T,
88    ) -> Result<UmbralResponse<()>, Box<dyn Error>> {
89        let body_bytes = serde_json::to_vec(&*request)?;
90        let request_body = Full::new(Bytes::from(body_bytes));
91
92        let request = Request::builder()
93            .method(Method::POST)
94            .uri(Uri::new(&self.socket, endpoint))
95            .header(header::CONTENT_TYPE, "application/json")
96            .body(request_body)?;
97
98        let response = self.full.request(request).await?;
99        let status = response.status().as_u16();
100        response.into_body().collect().await?;
101        return Ok(UmbralResponse::new(status, None));
102    }
103
104    pub async fn post_trigger(&self, endpoint: &str) -> Result<UmbralResponse<()>, Box<dyn Error>> {
105        let request_body = Empty::<Bytes>::new();
106        let request = Request::builder()
107            .method(Method::POST)
108            .uri(Uri::new(&self.socket, endpoint))
109            .header(header::CONTENT_LENGTH, "0")
110            .body(request_body)?;
111
112        let response = self.empty.request(request).await?;
113        let status = response.status().as_u16();
114        response.into_body().collect().await?;
115        return Ok(UmbralResponse::new(status, None));
116    }
117
118    pub async fn post_raw_bytes(
119        &self,
120        endpoint: &str,
121        body: Bytes,
122    ) -> Result<UmbralResponse<()>, Box<dyn Error>> {
123        let request_body = Full::new(body);
124        let request = Request::builder()
125            .method(Method::POST)
126            .uri(Uri::new(&self.socket, endpoint))
127            .header(header::CONTENT_TYPE, "application/json")
128            .body(request_body)?;
129        let response = self.full.request(request).await?;
130        let status = response.status();
131        response.into_body().collect().await?;
132        Ok(UmbralResponse::new(status.as_u16(), None))
133    }
134}