shared_resource_ipc/
lib.rs

1//! ## Shared Resource IPC
2//!
3//! A resource shared across processes. Supports any number of processes.
4//!
5
6use error::Error;
7use serde::{de::DeserializeOwned, Serialize};
8
9mod unix {
10    pub mod semaphore;
11    pub mod shared_mem;
12    pub mod unix;
13}
14
15mod error;
16
17use unix::unix::UnixSharedResource;
18
19trait SharedResourceBackend<T: Serialize + DeserializeOwned> {
20    /// Access an immutable reference to the shared resource using a clojure.
21    /// The clojure can return a value based on the reference to the resource.
22    ///
23    /// #### Arguments
24    /// - `accessor`: A clojure that accepts a value of type `&T` and returns a value of generic type `R`
25    ///
26    /// #### Returns
27    /// On success, returns the value of generic type `R`. On failure, returns an `Error`.
28    ///
29    fn access<F: Fn(&T) -> R, R>(&self, accessor: F) -> Result<R, Error>;
30
31    /// Access a mutable reference to the shared resource using a clojure.
32    /// The clojure can return a value based on the reference to the resource.
33    ///
34    /// #### Arguments
35    /// - `accessor`: A clojure that accepts a value of type `&mut T` and returns a value of generic type `R`
36    ///
37    /// #### Returns
38    /// On success, returns the value of generic type `R`. On failure, returns an `Error`.
39    ///
40    fn access_mut<F: Fn(&mut T) -> D, D>(&self, accessor: F) -> Result<D, Error>;
41}
42
43pub enum SharedResource<T: Serialize + DeserializeOwned> {
44    Unix(UnixSharedResource<T>),
45}
46
47impl<T: Serialize + DeserializeOwned> SharedResource<T> {
48    pub fn new(name: &str, initial_value: T) -> Result<SharedResource<T>, Error> {
49        // determine the OS
50        let shared_resource = match std::env::consts::OS {
51            "linux" => SharedResource::Unix(UnixSharedResource::<T>::new(name, initial_value)?),
52            "macos" => SharedResource::Unix(UnixSharedResource::<T>::new(name, initial_value)?),
53            _ => return Err(Error::UnsupportedOS),
54        };
55
56        return Ok(shared_resource);
57    }
58
59    /// Access an immutable reference to the shared resource using a clojure.
60    /// The clojure can return a value based on the reference to the resource.
61    ///
62    /// #### Arguments
63    /// - `accessor`: A clojure that accepts a value of type `&T` and returns a value of generic type `R`
64    ///
65    /// #### Returns
66    /// On success, returns the value of generic type `R`. On failure, returns an `Error`.
67    ///
68    pub fn access<F: Fn(&T) -> R, R>(&self, accessor: F) -> Result<R, Error> {
69        let resource = match self {
70            Self::Unix(res) => res,
71        };
72        resource.access(accessor)
73    }
74
75    /// Access a mutable reference to the shared resource using a clojure.
76    /// The clojure can return a value based on the reference to the resource.
77    ///
78    /// #### Arguments
79    /// - `accessor`: A clojure that accepts a value of type `&mut T` and returns a value of generic type `R`
80    ///
81    /// #### Returns
82    /// On success, returns the value of generic type `R`. On failure, returns an `Error`.
83    ///
84    pub fn access_mut<F: Fn(&mut T) -> D, D>(&self, accessor: F) -> Result<D, Error> {
85        let resource = match self {
86            Self::Unix(res) => res,
87        };
88        resource.access_mut(accessor)
89    }
90}