dusa_common/
prefix.rs

1use std::{io::{Read, Write}, os::unix::net::UnixStream};
2
3use serde::{Deserialize, Serialize};
4use dusa_collection_utils::errors::{ErrorArray, ErrorArrayItem, UnifiedResult};
5
6use crate::{DusaError, MessageType};
7
8#[derive(Serialize, Deserialize, Debug)]
9pub struct GeneralMessage {
10    pub version: String,
11    pub msg_type: MessageType,
12    pub payload: serde_json::Value,
13    pub error: Option<DusaError>,
14}
15
16/// Encodes a message with a length prefix and sends it over the stream.
17pub fn send_message<T: Serialize>(stream: &mut UnixStream, message: &T, mut errors: ErrorArray) -> UnifiedResult<()> {
18    let message_bytes = match serde_json::to_vec(message) {
19        Ok(d) => d,
20        Err(e) => {
21            errors.push(ErrorArrayItem::from(e));
22            return UnifiedResult::new(Err(errors))
23        },
24    };
25    let length = message_bytes.len() as u32;
26    let length_bytes = length.to_be_bytes(); // Convert length to big-endian bytes
27
28    // Send length prefix followed by the message
29    if let Err(err) = stream.write_all(&length_bytes) {
30        errors.push(ErrorArrayItem::from(err));
31        return UnifiedResult::new(Err(errors))
32    }
33
34    if let Err(err) = stream.write_all(&message_bytes) {
35        errors.push(ErrorArrayItem::from(err));
36        return UnifiedResult::new(Err(errors))
37    }
38
39    return UnifiedResult::new(Ok(()))
40}
41
42/// Reads a length-prefixed message from the stream and decodes it.
43pub fn receive_message(stream: &mut UnixStream, mut errors: ErrorArray) -> UnifiedResult<GeneralMessage> {
44    let mut length_bytes = [0u8; 4];
45
46    if let Err(err) = stream.read_exact(&mut length_bytes) {
47        errors.push(ErrorArrayItem::from(err));
48        return UnifiedResult::new(Err(errors))
49    }; // get the length
50
51    let length = u32::from_be_bytes(length_bytes) as usize;
52
53    let mut message_bytes = vec![0u8; length];
54
55    if let Err(err) = stream.read_exact(&mut message_bytes) {
56        errors.push(ErrorArrayItem::from(err));
57        return UnifiedResult::new(Err(errors))
58    } // Read the message
59
60    let message = match serde_json::from_slice(&message_bytes) {
61        Ok(d) => d,
62        Err(e) => {
63            errors.push(ErrorArrayItem::from(e));
64            return UnifiedResult::new(Err(errors))
65        },
66    };
67
68    UnifiedResult::new(Ok(message))
69}