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}