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}