r2d2/
extensions.rs

1use std::any::{Any, TypeId};
2use std::collections::HashMap;
3
4/// A "type map" used to associate data with pooled connections.
5///
6/// `Extensions` is a data structure mapping types to a value of that type. This
7/// can be used to, for example, cache prepared statements along side their
8/// connection.
9#[derive(Default)]
10pub struct Extensions(HashMap<TypeId, Box<dyn Any + Sync + Send>>);
11
12impl Extensions {
13    /// Returns a new, empty `Extensions`.
14    #[inline]
15    pub fn new() -> Extensions {
16        Extensions::default()
17    }
18
19    /// Inserts a new value into the map.
20    ///
21    /// Returns the previously stored value of that type, if present.
22    pub fn insert<T>(&mut self, value: T) -> Option<T>
23    where
24        T: 'static + Sync + Send,
25    {
26        self.0
27            .insert(TypeId::of::<T>(), Box::new(value))
28            .and_then(|v| Box::<dyn Any + 'static>::downcast(v).ok())
29            .map(|v| *v)
30    }
31
32    /// Returns a shared reference to the stored value of the specified type.
33    pub fn get<T>(&self) -> Option<&T>
34    where
35        T: 'static + Sync + Send,
36    {
37        self.0
38            .get(&TypeId::of::<T>())
39            .and_then(|v| v.downcast_ref())
40    }
41
42    /// Returns a mutable reference to the stored value of the specified type.
43    pub fn get_mut<T>(&mut self) -> Option<&mut T>
44    where
45        T: 'static + Sync + Send,
46    {
47        self.0
48            .get_mut(&TypeId::of::<T>())
49            .and_then(|v| v.downcast_mut())
50    }
51
52    /// Removes the value of the specified type from the map, returning it.
53    pub fn remove<T>(&mut self) -> Option<T>
54    where
55        T: 'static + Sync + Send,
56    {
57        self.0
58            .remove(&TypeId::of::<T>())
59            .and_then(|v| Box::<dyn Any + 'static>::downcast(v).ok())
60            .map(|v| *v)
61    }
62
63    /// Removes all values from the map.
64    #[inline]
65    pub fn clear(&mut self) {
66        self.0.clear();
67    }
68}