Skip to main content

vortex_session/
lib.rs

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