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::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        // TODO: fail to serialize in the network context.
62        serializer.serialize_str("<local>")
63    }
64}
65
66impl<'de, T> Deserialize<'de> for Local<T> {
67    fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
68    where
69        D: Deserializer<'de>,
70    {
71        Err(de::Error::custom("Local<T> cannot be deserialized"))
72    }
73}
74
75/// Used to transfer ownership over messaging.
76///
77/// Messages must be instances of `Clone`, `Serialize` and `Deserialize` because
78/// of network communication and message dumping. However, in some cases, it's
79/// desired to have messages that cannot satisfy requirements.
80/// For instance, when sending sockets or files.
81///
82/// `MoveOwnership<T>` implements `Debug`, `Clone`, `Serialize` and
83/// `Deserialize` for any `T`. Meanwhile, it can be serialized (but w/o useful
84/// information), it cannot be deserialized (it returns an error on attempts).
85///
86/// # Example
87/// ```ignore
88/// #[message]
89/// pub struct HandleFile {
90///     pub path: PathBuf,
91///     pub file: MoveOwnership<File>,
92/// }
93/// ```
94pub struct MoveOwnership<T>(Arc<Mutex<Option<T>>>);
95
96impl<T> MoveOwnership<T> {
97    /// Takes the value. Next calls will return `None`.
98    pub fn take(&self) -> Option<T> {
99        self.0.lock().take()
100    }
101}
102
103impl<T> From<T> for MoveOwnership<T> {
104    fn from(value: T) -> Self {
105        Self(Arc::new(Mutex::new(Some(value))))
106    }
107}
108
109impl<T> Clone for MoveOwnership<T> {
110    fn clone(&self) -> MoveOwnership<T> {
111        Self(self.0.clone())
112    }
113}
114
115impl<T> fmt::Debug for MoveOwnership<T> {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        write!(f, "<local>")
118    }
119}
120
121impl<T> Serialize for MoveOwnership<T> {
122    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
123    where
124        S: Serializer,
125    {
126        // TODO: fail to serialize in the network context.
127        serializer.serialize_str("<local>")
128    }
129}
130
131impl<'de, T> Deserialize<'de> for MoveOwnership<T> {
132    fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
133    where
134        D: Deserializer<'de>,
135    {
136        Err(de::Error::custom("MoveOwnership<T> cannot be deserialized"))
137    }
138}