nip_55/uds_req_res/
client.rs1use super::{UdsRequest, UdsResponse};
2use tokio::io::{AsyncReadExt, AsyncWriteExt};
3use tokio::net::UnixStream;
4
5#[derive(Clone)]
6pub struct UnixDomainSocketClientTransport {
7 uds_address: String,
8}
9
10impl UnixDomainSocketClientTransport {
11 pub fn new(uds_address: impl Into<String>) -> Self {
12 Self {
13 uds_address: uds_address.into(),
14 }
15 }
16
17 pub async fn send_request<Request: UdsRequest, Response: UdsResponse>(
18 &self,
19 request: Request,
20 ) -> Result<Response, UdsClientError> {
21 let serialized_request =
22 serde_json::to_vec(&request).map_err(|_| UdsClientError::RequestSerializationError)?;
23 let serialize_response = self.send_and_receive_bytes(serialized_request).await?;
24 serde_json::from_slice::<Response>(&serialize_response)
25 .map_err(|e| UdsClientError::MalformedResponse(e.into()))
26 }
27
28 async fn send_and_receive_bytes(
29 &self,
30 serialized_request: Vec<u8>,
31 ) -> Result<Vec<u8>, UdsClientError> {
32 let mut socket = UnixStream::connect(&self.uds_address)
34 .await
35 .map_err(|_| UdsClientError::ServerNotRunning)?;
36
37 socket
38 .write_all(&serialized_request)
39 .await
40 .map_err(|_| UdsClientError::UdsSocketError)?;
41 socket
42 .shutdown()
43 .await
44 .map_err(|_| UdsClientError::UdsSocketError)?;
45
46 let mut buf = Vec::new();
49 socket
50 .read_to_end(&mut buf)
51 .await
52 .map_err(|_| UdsClientError::UdsSocketError)?;
53 Ok(buf)
54 }
55}
56
57#[derive(Debug)]
59pub enum UdsClientError {
60 ServerNotRunning,
62
63 UdsSocketError,
65
66 RequestSerializationError,
68
69 MalformedResponse(anyhow::Error),
71}
72
73impl std::fmt::Display for UdsClientError {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 match self {
76 Self::ServerNotRunning => {
77 write!(f, "Unix domain socket server not running.")
78 }
79 Self::UdsSocketError => {
80 write!(f, "Error writing to or reading from Unix domain socket.")
81 }
82 Self::RequestSerializationError => {
83 write!(f, "Error serializing the request.")
84 }
85 Self::MalformedResponse(malformed_response_error) => {
86 write!(
87 f,
88 "Received a response from the server that that cannot be parsed ({malformed_response_error})."
89 )
90 }
91 }
92 }
93}
94
95impl std::error::Error for UdsClientError {}