horust_commands_lib/
client.rs

1use crate::proto::messages::horust_msg_message::MessageType;
2use crate::proto::messages::{
3    horust_msg_request, horust_msg_response, HorustMsgMessage, HorustMsgRequest,
4    HorustMsgServiceStatusRequest,
5};
6use crate::{HorustMsgServiceStatus, UdsConnectionHandler};
7use anyhow::{anyhow, Context};
8use anyhow::{bail, Result};
9use log::{debug, info};
10use std::net::Shutdown;
11use std::os::unix::net::UnixStream;
12use std::path::Path;
13
14fn new_request(request_type: horust_msg_request::Request) -> HorustMsgMessage {
15    HorustMsgMessage {
16        message_type: Some(MessageType::Request(HorustMsgRequest {
17            request: Some(request_type),
18        })),
19    }
20}
21
22// if anything is none it will return none
23// if the response was an error it will return Some(Err).
24fn unwrap_response(response: HorustMsgMessage) -> Option<Result<horust_msg_response::Response>> {
25    if let MessageType::Response(resp) = response.message_type? {
26        let v = resp.response?;
27        return match &v {
28            horust_msg_response::Response::Error(error) => {
29                Some(Err(anyhow!("Error: {}", error.error_string)))
30            }
31            horust_msg_response::Response::StatusResponse(_status) => Some(Ok(v)),
32        };
33    }
34    None
35}
36
37pub struct ClientHandler {
38    uds_connection_handler: UdsConnectionHandler,
39}
40impl ClientHandler {
41    pub fn new_client(socket_path: &Path) -> Result<Self> {
42        Ok(Self {
43            uds_connection_handler: UdsConnectionHandler::new(
44                UnixStream::connect(socket_path).context("Could not create stream")?,
45            ),
46        })
47    }
48    pub fn send_status_request(
49        &mut self,
50        service_name: String,
51    ) -> Result<(String, HorustMsgServiceStatus)> {
52        let status = new_request(horust_msg_request::Request::StatusRequest(
53            HorustMsgServiceStatusRequest { service_name },
54        ));
55        self.uds_connection_handler.send_message(status)?;
56        // server is waiting for EOF.
57        self.uds_connection_handler
58            .socket
59            .shutdown(Shutdown::Write)?;
60        //Reads all bytes until EOF in this source, appending them to buf.
61        let received = self.uds_connection_handler.receive_message()?;
62        debug!("Client: received: {received:?}");
63        let response = unwrap_response(received).unwrap()?;
64        if let horust_msg_response::Response::StatusResponse(resp) = response {
65            Ok((
66                resp.service_name,
67                HorustMsgServiceStatus::try_from(resp.service_status).unwrap(),
68            ))
69        } else {
70            bail!("Invalid response received: {:?}", response);
71        }
72    }
73
74    pub fn client(mut self, service_name: String) -> Result<()> {
75        let received = self.send_status_request(service_name)?;
76        info!("Client: received: {received:?}");
77        Ok(())
78    }
79}