libsignal_service/websocket/
request.rs

1use std::fmt;
2
3use reqwest::Method;
4use serde::Serialize;
5
6use crate::{
7    content::ServiceError,
8    proto::{WebSocketRequestMessage, WebSocketResponseMessage},
9    websocket::{SignalWebSocket, WebSocketType},
10};
11
12#[derive(Debug)]
13pub struct WebSocketRequestMessageBuilder {
14    request: WebSocketRequestMessage,
15}
16
17impl WebSocketRequestMessage {
18    #[allow(clippy::new_ret_no_self)]
19    pub fn new(method: Method) -> WebSocketRequestMessageBuilder {
20        WebSocketRequestMessageBuilder {
21            request: WebSocketRequestMessage {
22                verb: Some(method.to_string()),
23                ..Default::default()
24            },
25        }
26    }
27}
28
29impl WebSocketRequestMessageBuilder {
30    pub fn id(mut self, id: u64) -> Self {
31        self.request.id = Some(id);
32        self
33    }
34
35    pub fn path(mut self, path: impl Into<String>) -> Self {
36        self.request.path = Some(path.into());
37        self
38    }
39
40    pub fn header(mut self, key: &str, value: impl AsRef<str>) -> Self {
41        self.request
42            .headers
43            .push(format!("{key}:{}", value.as_ref()));
44        self
45    }
46
47    pub fn json<S: Serialize>(
48        mut self,
49        value: S,
50    ) -> Result<WebSocketRequestMessage, serde_json::Error> {
51        self.request.body = Some(serde_json::to_vec(&value)?);
52        Ok(self.header("content-type", "application/json").request)
53    }
54
55    pub fn build(self) -> WebSocketRequestMessage {
56        self.request
57    }
58}
59
60pub(crate) struct WebSocketRequestBuilder<'a, C: WebSocketType> {
61    ws: &'a mut SignalWebSocket<C>,
62    message_builder: WebSocketRequestMessageBuilder,
63}
64
65impl<C: WebSocketType> SignalWebSocket<C> {
66    #[tracing::instrument(skip(self))]
67    pub(crate) fn http_request(
68        &mut self,
69        method: Method,
70        path: impl Into<String> + fmt::Debug,
71    ) -> Result<WebSocketRequestBuilder<'_, C>, ServiceError> {
72        Ok(WebSocketRequestBuilder {
73            ws: self,
74            message_builder: WebSocketRequestMessage::new(method).path(path),
75        })
76    }
77}
78
79impl<C: WebSocketType> WebSocketRequestBuilder<'_, C> {
80    pub(crate) async fn send_json<B: Serialize>(
81        self,
82        value: B,
83    ) -> Result<WebSocketResponseMessage, ServiceError> {
84        let request = self.message_builder.json(value)?;
85        self.ws.request(request).await
86    }
87
88    pub(crate) async fn send(
89        self,
90    ) -> Result<WebSocketResponseMessage, ServiceError> {
91        let request = self.message_builder.build();
92        self.ws.request(request).await
93    }
94}