golang_ipc_rs/
lib.rs

1//! Implementation of a golang-ipc server and client.
2//!
3use flume::SendError;
4use std::sync::{
5    atomic::{AtomicUsize, Ordering},
6    Arc,
7};
8use tokio::sync::RwLock;
9
10pub mod client;
11pub mod message;
12pub mod mock_client;
13pub mod server;
14
15pub(crate) mod bichannel;
16pub(crate) mod connection;
17pub(crate) mod encryption;
18pub(crate) mod handshake;
19
20// Re-exports
21pub use client::{Client, Config as ClientConfig};
22pub use message::{Message, Status, Type};
23pub use server::{Config as ServerConfig, Server};
24
25pub const DEFAULT_CONNECTION_TIMEOUT: u64 = 60;
26pub const DEFAULT_RETRY_DELAY: u64 = 2;
27pub const DEFAULT_MSG_LENGTH: usize = 3145728; // 3Mb  - Maximum bytes allowed for each message
28
29#[derive(Default, Debug)]
30pub(crate) struct Context {
31    path: Arc<String>,
32    channel: Option<message::Channel>,
33    max_msg_length: Arc<AtomicUsize>,
34    encryption: bool,
35    status: Arc<RwLock<Status>>,
36    connection_timeout: u64,
37    retry_delay: u64,
38}
39
40impl<'a> Context {
41    pub(crate) fn set_channel(&mut self, channel: message::Channel) {
42        self.channel = Some(channel);
43    }
44
45    pub(crate) fn get_channel(&'a self) -> &'a message::Channel {
46        self.channel.as_ref().expect("Missing Channel")
47    }
48
49    pub(crate) fn get_encryption(&self) -> bool {
50        self.encryption
51    }
52
53    pub(crate) async fn set_status(&mut self, status: Status) {
54        *self.status.write().await = status;
55    }
56
57    pub(crate) async fn get_status(&mut self) -> Status {
58        *self.status.read().await
59    }
60
61    pub(crate) fn set_max_msg_length(&mut self, max_length: usize) {
62        self.max_msg_length.store(max_length, Ordering::Relaxed);
63    }
64
65    pub(crate) fn get_max_msg_length(&self) -> usize {
66        self.max_msg_length.load(Ordering::Relaxed)
67    }
68
69    pub(crate) async fn recv_message(&self) -> Option<Message> {
70        self.get_channel().recv().await
71    }
72
73    pub(crate) async fn send_message(
74        &self,
75        message: Message,
76    ) -> std::result::Result<(), SendError<Message>> {
77        if message.data_length() > self.get_max_msg_length() {
78            Err(SendError(message))?
79        } else {
80            self.get_channel().send(message).await
81        }
82    }
83
84    pub(crate) async fn report_status(&mut self, status: Status) -> crate::Result<()> {
85        self.set_status(status).await;
86
87        self.get_channel()
88            .send(Message::from_status(status))
89            .await?;
90
91        Ok(())
92    }
93
94    pub(crate) async fn report_error_status(&mut self, err: crate::Error) {
95        let _ = self.report_status(Status::Error).await;
96        let _ = self.get_channel().send(Message::from_error(err)).await;
97    }
98}
99
100impl std::clone::Clone for Context {
101    fn clone(&self) -> Self {
102        Context {
103            path: self.path.clone(),
104            channel: None, // channel does not implement Clone
105            max_msg_length: self.max_msg_length.clone(),
106            encryption: self.encryption,
107            status: self.status.clone(),
108            connection_timeout: self.connection_timeout,
109            retry_delay: self.retry_delay,
110        }
111    }
112}
113
114/// Error returned by most functions.
115///
116// pub type Error = Box<dyn std::io::Error + Send + Sync>;
117pub type Error = anyhow::Error;
118
119/// A specialized `Result` type for golang-ipc-rs operations.
120///
121/// This is defined as a convenience.
122pub type Result<T> = std::result::Result<T, Error>;