interns/backend/
mod.rs

1mod string_buf;
2use std::hash::Hash;
3
4mod vec;
5pub use vec::VecBackend;
6
7pub use string_buf::StringBuf;
8
9/// Allows to specify a default backend for some type
10///
11/// # Example
12/// ```
13/// use interns::DefaultBackendBuilder;
14///
15/// /* Get the default backend for the str type */
16/// let backend = <str as DefaultBackendBuilder>::build_backend();
17/// ```
18pub trait DefaultBackendBuilder {
19    type Backend: Backend<Self>;
20    fn build_backend() -> Self::Backend;
21}
22
23pub type DefaultBackend<T> = <T as DefaultBackendBuilder>::Backend;
24
25impl<T: Sized + Clone> DefaultBackendBuilder for T {
26    type Backend = VecBackend<T>;
27
28    fn build_backend() -> Self::Backend {
29        VecBackend::default()
30    }
31}
32
33impl DefaultBackendBuilder for str {
34    type Backend = StringBuf;
35
36    fn build_backend() -> Self::Backend {
37        StringBuf::default()
38    }
39}
40
41pub trait BackendSymbol: Clone + Copy + Hash + Eq + PartialEq {}
42impl<T> BackendSymbol for T where T: Clone + Copy + Hash + Eq + PartialEq {}
43
44/// Backend for the [Interner](super::Interner)
45pub trait Backend<T: ?Sized> {
46    type Symbol: BackendSymbol;
47
48    /// Intern the element
49    fn intern(&mut self, src: &T) -> Self::Symbol;
50
51    /// Resolve the symbol
52    fn get(&self, sym: Self::Symbol) -> Option<&T>;
53
54    /// Resolves the symbol, without checking if it exists on
55    /// the backend.
56    ///
57    /// # Safety
58    /// The caller must ensure that the symbol was retreived
59    /// from a call to this backend's [intern](Backend::intern) function.
60    unsafe fn get_unchecked(&self, sym: Self::Symbol) -> &T {
61        let val = self.get(sym);
62        debug_assert!(val.is_some());
63        /* SAFETY: the caller ensures that the symbol is valid for `self` */
64        unsafe { val.unwrap_unchecked() }
65    }
66}