Skip to main content

moire_types/
lib.rs

1//! Core graph nomenclature used across Peep's runtime model.
2//!
3//! - `Event`: a point-in-time occurrence with a timestamp.
4//! - `Entity`: a runtime thing that exists over time (for example a lock,
5//!   future, channel, request, or connection).
6//! - `Edge`: a relationship between entities (causal or structural).
7//! - `Scope`: an execution container that groups entities (for example a
8//!   process, thread, or task).
9//!
10//! r[impl model.summary]
11//! In short: events happen to entities, entities are connected by edges,
12//! and entities live inside scopes.
13
14#[macro_export]
15macro_rules! impl_sqlite_json {
16    ($ty:ty) => {
17        #[cfg(feature = "rusqlite")]
18        impl ::rusqlite::types::ToSql for $ty {
19            fn to_sql(&self) -> ::rusqlite::Result<::rusqlite::types::ToSqlOutput<'_>> {
20                let json = ::facet_json::to_string(self).map_err(|err| {
21                    ::rusqlite::Error::ToSqlConversionFailure(Box::new(::std::io::Error::new(
22                        ::std::io::ErrorKind::InvalidData,
23                        err.to_string(),
24                    )))
25                })?;
26                Ok(json.into())
27            }
28        }
29
30        #[cfg(feature = "rusqlite")]
31        impl ::rusqlite::types::FromSql for $ty {
32            fn column_result(
33                value: ::rusqlite::types::ValueRef<'_>,
34            ) -> ::rusqlite::types::FromSqlResult<Self> {
35                let json = <String as ::rusqlite::types::FromSql>::column_result(value)?;
36                ::facet_json::from_str(&json).map_err(|err| {
37                    ::rusqlite::types::FromSqlError::Other(Box::new(::std::io::Error::new(
38                        ::std::io::ErrorKind::InvalidData,
39                        err.to_string(),
40                    )))
41                })
42            }
43        }
44    };
45}
46
47#[macro_export]
48macro_rules! impl_entity_body_slot {
49    ($slot:ident :: $variant:ident ($value:ty)) => {
50        impl $crate::EntityBodySlot for $slot {
51            type Value = $value;
52            const KIND_NAME: &'static str = stringify!($variant);
53
54            fn project(body: &$crate::EntityBody) -> Option<&Self::Value> {
55                if let $crate::EntityBody::$variant(value) = body {
56                    Some(value)
57                } else {
58                    None
59                }
60            }
61
62            fn project_mut(body: &mut $crate::EntityBody) -> Option<&mut Self::Value> {
63                if let $crate::EntityBody::$variant(value) = body {
64                    Some(value)
65                } else {
66                    None
67                }
68            }
69        }
70    };
71    ($slot:ty, $value:ty, $variant:ident, $kind_name:expr) => {
72        impl $crate::EntityBodySlot for $slot {
73            type Value = $value;
74            const KIND_NAME: &'static str = $kind_name;
75
76            fn project(body: &$crate::EntityBody) -> Option<&Self::Value> {
77                if let $crate::EntityBody::$variant(value) = body {
78                    Some(value)
79                } else {
80                    None
81                }
82            }
83
84            fn project_mut(body: &mut $crate::EntityBody) -> Option<&mut Self::Value> {
85                if let $crate::EntityBody::$variant(value) = body {
86                    Some(value)
87                } else {
88                    None
89                }
90            }
91        }
92    };
93}
94
95#[macro_export]
96macro_rules! define_entity_body {
97    (
98        $vis:vis enum EntityBody {
99            $(
100                $(#[$variant_meta:meta])*
101                $variant:ident($value:ty)
102            ),+ $(,)?
103        }
104    ) => {
105        #[derive(::facet::Facet)]
106        #[repr(u8)]
107        #[facet(rename_all = "snake_case")]
108        #[allow(dead_code)]
109        $vis enum EntityBody {
110            $(
111                $(#[$variant_meta])*
112                $variant($value),
113            )+
114        }
115
116        impl EntityBody {
117            pub fn kind_name(&self) -> &'static str {
118                match self {
119                    $(
120                        Self::$variant(_) => stringify!($variant),
121                    )+
122                }
123            }
124        }
125
126        $crate::impl_sqlite_json!(EntityBody);
127
128        $(
129            impl ::core::convert::From<$value> for EntityBody {
130                fn from(value: $value) -> Self {
131                    Self::$variant(value)
132                }
133            }
134
135            $crate::impl_entity_body_slot!($value, $value, $variant, stringify!($variant));
136            pub type $variant = $value;
137        )+
138    };
139}
140
141#[macro_export]
142macro_rules! declare_entity_body_slots {
143    ($( $slot:ident :: $variant:ident ($value:ty) ),+ $(,)?) => {
144        $(
145            pub struct $slot;
146            $crate::impl_entity_body_slot!($slot::$variant($value));
147        )+
148    };
149}
150
151#[macro_export]
152macro_rules! impl_scope_body_slot {
153    ($slot:ident :: $variant:ident ($value:ty)) => {
154        impl $crate::ScopeBodySlot for $slot {
155            type Value = $value;
156            const KIND_NAME: &'static str = stringify!($variant);
157
158            fn project(body: &$crate::ScopeBody) -> Option<&Self::Value> {
159                if let $crate::ScopeBody::$variant(value) = body {
160                    Some(value)
161                } else {
162                    None
163                }
164            }
165
166            fn project_mut(body: &mut $crate::ScopeBody) -> Option<&mut Self::Value> {
167                if let $crate::ScopeBody::$variant(value) = body {
168                    Some(value)
169                } else {
170                    None
171                }
172            }
173        }
174    };
175    ($slot:ty, $value:ty, $variant:ident, $kind_name:expr) => {
176        impl $crate::ScopeBodySlot for $slot {
177            type Value = $value;
178            const KIND_NAME: &'static str = $kind_name;
179
180            fn project(body: &$crate::ScopeBody) -> Option<&Self::Value> {
181                if let $crate::ScopeBody::$variant(value) = body {
182                    Some(value)
183                } else {
184                    None
185                }
186            }
187
188            fn project_mut(body: &mut $crate::ScopeBody) -> Option<&mut Self::Value> {
189                if let $crate::ScopeBody::$variant(value) = body {
190                    Some(value)
191                } else {
192                    None
193                }
194            }
195        }
196    };
197}
198
199#[macro_export]
200macro_rules! declare_scope_body_slots {
201    ($( $slot:ident :: $variant:ident ($value:ty) ),+ $(,)?) => {
202        $(
203            pub struct $slot;
204            $crate::impl_scope_body_slot!($slot::$variant($value));
205        )+
206    };
207}
208
209#[macro_export]
210macro_rules! impl_event_target_slot {
211    ($slot:ident :: $variant:ident ($value:ty)) => {
212        impl $crate::EventTargetSlot for $slot {
213            type Value = $value;
214            const KIND_NAME: &'static str = stringify!($variant);
215
216            fn project(target: &$crate::EventTarget) -> Option<&Self::Value> {
217                if let $crate::EventTarget::$variant(value) = target {
218                    Some(value)
219                } else {
220                    None
221                }
222            }
223
224            fn project_mut(target: &mut $crate::EventTarget) -> Option<&mut Self::Value> {
225                if let $crate::EventTarget::$variant(value) = target {
226                    Some(value)
227                } else {
228                    None
229                }
230            }
231        }
232    };
233    ($slot:ty, $value:ty, $variant:ident, $kind_name:expr) => {
234        impl $crate::EventTargetSlot for $slot {
235            type Value = $value;
236            const KIND_NAME: &'static str = $kind_name;
237
238            fn project(target: &$crate::EventTarget) -> Option<&Self::Value> {
239                if let $crate::EventTarget::$variant(value) = target {
240                    Some(value)
241                } else {
242                    None
243                }
244            }
245
246            fn project_mut(target: &mut $crate::EventTarget) -> Option<&mut Self::Value> {
247                if let $crate::EventTarget::$variant(value) = target {
248                    Some(value)
249                } else {
250                    None
251                }
252            }
253        }
254    };
255}
256
257#[macro_export]
258macro_rules! declare_event_target_slots {
259    ($( $slot:ident :: $variant:ident ($value:ty) ),+ $(,)?) => {
260        $(
261            pub struct $slot;
262            $crate::impl_event_target_slot!($slot::$variant($value));
263        )+
264    };
265}
266
267#[macro_export]
268macro_rules! impl_event_kind_slot {
269    ($slot:ident :: $variant:ident) => {
270        impl $crate::EventKindSlot for $slot {
271            const KIND: $crate::EventKind = $crate::EventKind::$variant;
272            const KIND_NAME: &'static str = stringify!($variant);
273        }
274    };
275    ($slot:ty, $variant:ident, $kind_name:expr) => {
276        impl $crate::EventKindSlot for $slot {
277            const KIND: $crate::EventKind = $crate::EventKind::$variant;
278            const KIND_NAME: &'static str = $kind_name;
279        }
280    };
281}
282
283#[macro_export]
284macro_rules! declare_event_kind_slots {
285    ($( $slot:ident :: $variant:ident ),+ $(,)?) => {
286        $(
287            pub struct $slot;
288            $crate::impl_event_kind_slot!($slot::$variant);
289        )+
290    };
291}
292
293#[macro_export]
294macro_rules! impl_edge_kind_slot {
295    ($slot:ident :: $variant:ident) => {
296        impl $crate::EdgeKindSlot for $slot {
297            const KIND: $crate::EdgeKind = $crate::EdgeKind::$variant;
298            const KIND_NAME: &'static str = stringify!($variant);
299        }
300    };
301    ($slot:ty, $variant:ident, $kind_name:expr) => {
302        impl $crate::EdgeKindSlot for $slot {
303            const KIND: $crate::EdgeKind = $crate::EdgeKind::$variant;
304            const KIND_NAME: &'static str = $kind_name;
305        }
306    };
307}
308
309#[macro_export]
310macro_rules! declare_edge_kind_slots {
311    ($( $slot:ident :: $variant:ident ),+ $(,)?) => {
312        $(
313            pub struct $slot;
314            $crate::impl_edge_kind_slot!($slot::$variant);
315        )+
316    };
317}
318
319pub(crate) mod api;
320pub(crate) mod diff;
321pub(crate) mod objects;
322pub(crate) mod primitives;
323pub(crate) mod recording;
324pub(crate) mod snapshots;
325pub(crate) mod sources;
326
327pub use api::*;
328pub use diff::*;
329pub use objects::*;
330pub use primitives::*;
331pub use recording::*;
332pub use snapshots::*;
333pub use sources::*;