Skip to main content

elfo_core/
local.rs

1use std::{fmt, ops::Deref, sync::Arc};
2
3use derive_more::From;
4use parking_lot::Mutex;
5use serde::{
6    de::{self, Deserializer},
7    ser::{self, Serializer},
8    Deserialize, Serialize,
9};
10
11/// Used to send values that cannot be serialized.
12/// Works inside the current node only.
13///
14/// Messages must be instances of `Clone`, `Serialize` and `Deserialize` because
15/// of network communication and message dumping. However, in some cases, it's
16/// desired to have messages that cannot satisfy requirements.
17/// For instance, when sending channels.
18///
19/// `Local<T>` implements `Debug`, `Serialize` and `Deserialize` for any `T`.
20/// Meanwhile, it can be serialized (but w/o useful information), it cannot be
21/// deserialized (it returns an error on attempts).
22///
23/// # Example
24/// ```ignore
25/// #[message]
26/// pub struct OpenDirectChannel {
27///     pub tx: Local<mpsc::Sender>,
28/// }
29/// ```
30#[derive(Clone, Copy, PartialEq, Eq, Default, From)]
31pub struct Local<T>(T);
32
33impl<T> Local<T> {
34    #[inline]
35    pub fn into_inner(self) -> T {
36        self.0
37    }
38}
39
40impl<T> Deref for Local<T> {
41    type Target = T;
42
43    #[inline]
44    fn deref(&self) -> &Self::Target {
45        &self.0
46    }
47}
48
49impl<T> fmt::Debug for Local<T> {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        write!(f, "<local>")
52    }
53}
54
55impl<T> Serialize for Local<T> {
56    #[inline]
57    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
58    where
59        S: Serializer,
60    {
61        if crate::scope::serde_mode() == crate::scope::SerdeMode::Network {
62            Err(ser::Error::custom("Local<T> cannot be sent over network"))
63        } else {
64            serializer.serialize_str("<local>")
65        }
66    }
67}
68
69impl<'de, T> Deserialize<'de> for Local<T> {
70    fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
71    where
72        D: Deserializer<'de>,
73    {
74        Err(de::Error::custom("Local<T> cannot be deserialized"))
75    }
76}
77
78/// Used to transfer ownership over messaging.
79///
80/// Messages must be instances of `Clone`, `Serialize` and `Deserialize` because
81/// of network communication and message dumping. However, in some cases, it's
82/// desired to have messages that cannot satisfy requirements.
83/// For instance, when sending sockets or files.
84///
85/// `MoveOwnership<T>` implements `Debug`, `Clone`, `Serialize` and
86/// `Deserialize` for any `T`. Meanwhile, it can be serialized (but w/o useful
87/// information), it cannot be deserialized (it returns an error on attempts).
88///
89/// # Example
90/// ```ignore
91/// #[message]
92/// pub struct HandleFile {
93///     pub path: PathBuf,
94///     pub file: MoveOwnership<File>,
95/// }
96/// ```
97pub struct MoveOwnership<T>(Arc<Mutex<Option<T>>>);
98
99impl<T> MoveOwnership<T> {
100    /// Takes the value. Next calls will return `None`.
101    pub fn take(&self) -> Option<T> {
102        self.0.lock().take()
103    }
104}
105
106impl<T> From<T> for MoveOwnership<T> {
107    fn from(value: T) -> Self {
108        Self(Arc::new(Mutex::new(Some(value))))
109    }
110}
111
112impl<T> Clone for MoveOwnership<T> {
113    fn clone(&self) -> MoveOwnership<T> {
114        Self(self.0.clone())
115    }
116}
117
118impl<T> fmt::Debug for MoveOwnership<T> {
119    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120        write!(f, "<local>")
121    }
122}
123
124impl<T> Serialize for MoveOwnership<T> {
125    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
126    where
127        S: Serializer,
128    {
129        if crate::scope::serde_mode() == crate::scope::SerdeMode::Network {
130            Err(ser::Error::custom(
131                "MoveOwnership<T> cannot be sent over network",
132            ))
133        } else {
134            serializer.serialize_str("<local>")
135        }
136    }
137}
138
139impl<'de, T> Deserialize<'de> for MoveOwnership<T> {
140    fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
141    where
142        D: Deserializer<'de>,
143    {
144        Err(de::Error::custom("MoveOwnership<T> cannot be deserialized"))
145    }
146}