Skip to main content

vortex_session/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4mod arc_swap_map;
5pub mod registry;
6mod session;
7
8use std::any::Any;
9use std::fmt::Debug;
10use std::hash::Hasher;
11
12pub use arc_swap_map::ArcSwapMap;
13pub use session::SessionGuard;
14pub use session::SessionMut;
15pub use session::VortexSession;
16pub use session::VortexSessionVar;
17
18#[derive(Debug, Clone, Copy, Default)]
19struct UnknownPluginPolicy {
20    allow_unknown: bool,
21}
22
23impl SessionVar for UnknownPluginPolicy {
24    fn as_any(&self) -> &dyn Any {
25        self
26    }
27
28    fn as_any_mut(&mut self) -> &mut dyn Any {
29        self
30    }
31}
32
33/// Trait for accessing the state of a Vortex session.
34pub trait SessionExt: Sized + private::Sealed {
35    /// Returns the [`VortexSession`].
36    fn session(&self) -> VortexSession;
37
38    /// Returns the session variable of type `V`, inserting a default one if it does not exist.
39    ///
40    /// The default is constructed and inserted copy-on-write: `V::default()` runs without any lock
41    /// held, so it may freely re-enter the session, and a concurrent insert of the same type is
42    /// resolved by keeping the first value published.
43    fn get<V: VortexSessionVar + Default>(&self) -> SessionGuard<'_, V>;
44
45    /// Returns the session variable of type `V` if it exists.
46    fn get_opt<V: VortexSessionVar>(&self) -> Option<SessionGuard<'_, V>>;
47
48    /// Returns a copy-on-write [`SessionMut`] handle for the variable of type `V`, inserting a
49    /// default one first if it does not exist.
50    ///
51    /// The handle starts as a clone of the current value; mutating it through `DerefMut` and
52    /// dropping it publishes the result back into the session copy-on-write — the ergonomic
53    /// equivalent of reading the variable, modifying a clone, and re-inserting it into the session.
54    fn get_mut<V: VortexSessionVar + Default + Clone>(&self) -> SessionMut<'_, V>;
55}
56
57mod private {
58    pub trait Sealed {}
59    impl Sealed for super::VortexSession {}
60}
61
62/// This trait defines variables that can be stored against a Vortex session.
63///
64/// Users should implement this trait for anything that you want to store on a `VortexSession`.
65pub trait SessionVar: Any + Send + Sync + Debug + 'static {
66    fn as_any(&self) -> &dyn Any;
67    fn as_any_mut(&mut self) -> &mut dyn Any;
68}
69
70/// With TypeIds as keys, there's no need to hash them. They are already hashes
71/// themselves, coming from the compiler. The IdHasher just holds the u64 of
72/// the TypeId, and then returns it, instead of doing any bit fiddling.
73#[derive(Default)]
74struct IdHasher(u64);
75
76impl Hasher for IdHasher {
77    #[inline]
78    fn finish(&self) -> u64 {
79        self.0
80    }
81
82    fn write(&mut self, _: &[u8]) {
83        unreachable!("TypeId calls write_u64");
84    }
85
86    #[inline]
87    fn write_u64(&mut self, id: u64) {
88        self.0 = id;
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use super::VortexSession;
95
96    #[test]
97    fn allow_unknown_flag_is_opt_in() {
98        let session = VortexSession::empty();
99        assert!(!session.allows_unknown());
100
101        session.allow_unknown();
102        assert!(session.allows_unknown());
103    }
104}