inc_complete/computation/
singleton.rs

1use crate::{Cell, DbHandle};
2
3use super::Computation;
4
5/// Helper to define a Computation for a simple input type which has no fields and thus
6/// does not require a HashMap to cache each possible value.
7///
8/// Examples include `struct SourceFile;` or `struct Time;`
9#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
10pub struct SingletonStorage<T>(T);
11
12impl<T> SingletonStorage<T> {
13    pub fn new(value: T) -> Self {
14        let bytes = std::mem::size_of::<T>();
15        assert_eq!(
16            bytes,
17            0,
18            "SingletonStorage only supports 0-sized types but `{}` is `{}` bytes large",
19            std::any::type_name::<T>(),
20            bytes
21        );
22        Self(value)
23    }
24}
25
26impl<T: Computation> Computation for SingletonStorage<T> {
27    type Output = <T as Computation>::Output;
28    type Storage = (
29        Option<Cell>,
30        // Self is required here to return a reference to it in `get_function_and_output`
31        Self,
32        Option<Self::Output>,
33    );
34
35    fn run(&self, handle: &mut DbHandle<impl Computation>) -> Self::Output {
36        self.0.run(handle)
37    }
38
39    fn input_to_cell(_: &Self, storage: &Self::Storage) -> Option<Cell> {
40        storage.0
41    }
42
43    fn get_function_and_output(_: Cell, storage: &Self::Storage) -> (&Self, Option<&Self::Output>) {
44        (&storage.1, storage.2.as_ref())
45    }
46
47    fn set_output(_: Cell, new_output: Self::Output, storage: &mut Self::Storage) {
48        storage.2 = Some(new_output);
49    }
50
51    fn insert_new_cell(cell: Cell, this: Self, storage: &mut Self::Storage) {
52        *storage = (Some(cell), this, None);
53    }
54}