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!(bytes, 0, "SingletonStorage only supports 0-sized types but `{}` is `{}` bytes large",
16            std::any::type_name::<T>(), bytes);
17        Self(value)
18    }
19}
20
21impl<T: Computation> Computation for SingletonStorage<T> {
22    type Output = <T as Computation>::Output;
23    type Storage = (
24        Option<Cell>,
25        // Self is required here to return a reference to it in `get_function_and_output`
26        Self,
27        Option<Self::Output>,
28    );
29
30    fn run(&self, handle: &mut DbHandle<impl Computation>) -> Self::Output {
31        self.0.run(handle)
32    }
33
34    fn input_to_cell(_: &Self, storage: &Self::Storage) -> Option<Cell> {
35        storage.0
36    }
37
38    fn get_function_and_output(_: Cell, storage: &Self::Storage) -> (&Self, Option<&Self::Output>) {
39        (&storage.1, storage.2.as_ref())
40    }
41
42    fn set_output(_: Cell, new_output: Self::Output, storage: &mut Self::Storage) {
43        storage.2 = Some(new_output);
44    }
45
46    fn insert_new_cell(cell: Cell, this: Self, storage: &mut Self::Storage) {
47        *storage = (Some(cell), this, None);
48    }
49}